Related
I have two arrays each containing 100 digits.I need to add corresponding digits from units place meaning from the end of the array.If there is a carry it should be added in the next index.It should return another array containing the sum.
Here is my code and something seems to be wrong .Help me
void sumOf100DigitNumbers(int num1[100], int num2[100], int sum[101]) {
int i, j = 100, k;
for (i = 99; i >= 0; i--)
{
if (sum[j] == 1)
{
}
else
sum[j] = 0;
k = sum[j] + num1[i] + num2[i];
if (k >= 10)
{
sum[j] = k % 10;
sum[j - 1] = 1;
}
else
{
sum[j] = k;
}
j--;
}
}
Method to test it
[TestMethod, Timeout(1000)]
void Test_sumOf100DigitNumbers2()
{
int a[100] = {6, 8, 3, 7, 8, 1, 2, 4, 6, 7, 2, 0, 6, 6, 7, 0, 0, 9, 4, 8, 2, 9, 6, 3, 1, 7, 2, 3, 0, 4, 4, 5, 0, 9, 7, 0, 8, 9, 2, 6, 9, 2, 8, 8, 0, 2, 8, 2, 6, 5, 3, 0, 5, 2, 2, 5, 8, 8, 6, 6, 2, 3, 6, 0, 7, 0, 9, 9, 0, 4, 6, 4, 0, 4, 5, 1, 9, 5, 1, 5, 3, 6, 6, 3, 2, 4, 0, 7, 7, 8, 4, 6, 8, 7, 8, 9, 1, 6, 9, 2};
int b[100] = { 4, 1, 4, 1, 5, 0, 1, 8, 4, 5, 9, 7, 6, 2, 2, 0, 1, 7, 2, 5, 0, 3, 6, 9, 0, 8, 7, 3, 0, 2, 7, 8, 6, 5, 7, 3, 6, 8, 4, 2, 9, 2, 4, 8, 2, 1, 1, 0, 6, 6, 2, 7, 2, 8, 9, 7, 2, 4, 2, 2, 7, 6, 0, 7, 2, 3, 8, 4, 2, 5, 4, 7, 1, 8, 9, 9, 7, 0, 3, 2, 5, 1, 9, 7, 1, 0, 0, 0, 2, 1, 1, 5, 9, 0, 0, 1, 6, 6, 9, 7 };
int ans[101] = { 1, 0, 9, 7, 9, 3, 1, 4, 3, 1, 3, 1, 8, 2, 8, 9, 0, 2, 6, 7, 3, 3, 3, 3, 2, 2, 5, 9, 6, 0, 7, 2, 3, 7, 5, 4, 4, 5, 7, 6, 9, 8, 5, 3, 6, 2, 3, 9, 3, 3, 1, 5, 7, 8, 1, 2, 3, 1, 2, 8, 8, 9, 9, 6, 7, 9, 4, 8, 3, 3, 0, 1, 1, 2, 3, 5, 1, 6, 5, 4, 7, 8, 8, 6, 0, 3, 4, 0, 7, 9, 9, 6, 2, 7, 7, 9, 0, 8, 3, 8, 9 };
int c[101];
sumOf100DigitNumbers(a, b, c);
Assert::AreEqual(true, areEqualArrays(ans, c, 101), L"sumOf100DigitNumbers() failed", 1, 2);
};
but my output is as follows:
Output
You never initialize c. This means that its contents are indeterminate. You can't predict what values it will contain.
So when you do this:
if (sum[j] == 1)
If one of those indeterminate values happens to be 1 then you're performing a carry you don't intend on doing.
You can initialize it as follows:
int c[101] = { 0 };
Then you can remove this entirely:
if (sum[j] == 1)
{
}
else
sum[j] = 0;
Is there an efficient way to resize an image in OpenCV without using any interpolation? Instead of the conventional "resize" I would like my image to remap the pixels into a larger image but pad everything else with 0.
e.g. to scale up img1 below 2x to img2:
img1 = [ 1, 2, 3,
4, 5, 6,
7, 8, 9 ]
cv::resize(img1, img2, cv::Size(6, 6));
img2 = [ 1, 0, 2, 0, 3, 0,
0, 0, 0, 0, 0, 0,
4, 0, 5, 0, 6, 0,
0, 0, 0, 0, 0, 0,
7, 0, 8, 0, 9, 0,
0, 0, 0, 0, 0, 0 ]
I know the obvious way is to just use a for loop, but I'm wondering if there is a more efficient way using an OpenCV call?
One option that comes to mind would be to use cv::resize with INTER_NEAREST and then mask out the unwanted pixels.
Example:
#include <opencv2/opencv.hpp>
#include <cstdint>
#include <iostream>
int main()
{
cv::Mat m1((cv::Mat_<uint8_t>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9));
std::cout << "Input:\n" << m1 << "\n\n";
cv::Mat mask((cv::Mat_<uint8_t>(2, 2) << 255, 0, 0, 0));
mask = cv::repeat(mask, m1.rows, m1.cols);
std::cout << "Mask:\n" << mask << "\n\n";
cv::Mat m2;
cv::resize(m1, m2, cv::Size(), 2, 2, cv::INTER_NEAREST);
std::cout << "Resized:\n" << m2 << "\n\n";
cv::bitwise_and(m2, mask, m2);
std::cout << "Masked:\n" << m2 << "\n\n";
}
Console output:
Input:
[ 1, 2, 3;
4, 5, 6;
7, 8, 9]
Mask:
[255, 0, 255, 0, 255, 0;
0, 0, 0, 0, 0, 0;
255, 0, 255, 0, 255, 0;
0, 0, 0, 0, 0, 0;
255, 0, 255, 0, 255, 0;
0, 0, 0, 0, 0, 0]
Resized:
[ 1, 1, 2, 2, 3, 3;
1, 1, 2, 2, 3, 3;
4, 4, 5, 5, 6, 6;
4, 4, 5, 5, 6, 6;
7, 7, 8, 8, 9, 9;
7, 7, 8, 8, 9, 9]
Masked:
[ 1, 0, 2, 0, 3, 0;
0, 0, 0, 0, 0, 0;
4, 0, 5, 0, 6, 0;
0, 0, 0, 0, 0, 0;
7, 0, 8, 0, 9, 0;
0, 0, 0, 0, 0, 0]
Update
If we eliminate parts of Miki's code that are unnecessary for our specific scenario, we pretty much reduce it to a simple loop.
Doing some quick comparisons, this turns out to be somewhat faster.
#include <opencv2/opencv.hpp>
#include <chrono>
#include <cstdint>
#include <iostream>
cv::Mat resize_1(cv::Mat image)
{
cv::Mat result(cv::Mat::zeros(image.rows * 2, image.cols * 2, CV_8UC1));
for (int ra(0); ra < image.rows; ++ra) {
for (int ca = 0; ca < image.cols; ++ca) {
result.at<uint8_t>(ra * 2, ca * 2) = image.at<uint8_t>(ra, ca);
}
}
return result;
}
cv::Mat resize_2(cv::Mat image)
{
cv::Mat mask((cv::Mat_<uint8_t>(2, 2) << 255, 0, 0, 0));
mask = cv::repeat(mask, image.rows, image.cols);
cv::Mat result;
cv::resize(image, result, cv::Size(), 2, 2, cv::INTER_NEAREST);
cv::bitwise_and(result, mask, result);
return result;
}
template<typename T>
void timeit(T f)
{
using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::microseconds;
cv::Mat m1((cv::Mat_<uint8_t>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9));
m1 = cv::repeat(m1, 1024, 1024);
high_resolution_clock::time_point t1 = high_resolution_clock::now();
for (uint32_t i(0); i < 256; ++i) {
cv::Mat result = f(m1);
}
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(t2 - t1).count();
double t_ms(static_cast<double>(duration) / 1000.0);
std::cout
<< "Total = " << t_ms << " ms\n"
<< "Iteration = " << (t_ms / 256) << " ms\n"
<< "FPS = " << (256 / t_ms * 1000.0) << "\n";
}
int main()
{
timeit(&resize_1);
timeit(&resize_2);
}
Timing:
resize_1
Total = 6344.86 ms
Iteration = 24.7846 ms
FPS = 40.3476
resize_2
Total = 7271.31 ms
Iteration = 28.4036 ms
FPS = 35.2068
Update 2
Parallelized version:
class ResizeInvoker : public cv::ParallelLoopBody
{
public:
ResizeInvoker(cv::Mat const& src, cv::Mat& dst)
: image(src)
, result(dst)
{
}
void operator()(const cv::Range& range) const
{
for (int y(range.start); y < (range.end); ++y) {
for (int x(0); x < image.cols; ++x) {
result.at<uint8_t>(y * 2, x * 2) = image.at<uint8_t>(y, x);
}
}
}
cv::Mat const& image;
cv::Mat& result;
};
cv::Mat resize_3(cv::Mat image)
{
cv::Mat result(cv::Mat::zeros(image.rows * 2, image.cols * 2, CV_8UC1));
ResizeInvoker loop_body(image, result);
cv::parallel_for_(cv::Range(0, image.rows)
, loop_body
, result.total() / (double)(1 << 16));
return result;
}
Timing:
resize_3
Total = 3876.63 ms
Iteration = 15.1431 ms
FPS = 66.0367
Update 3
We can do a little better if we use raw pointers in the invoker:
void operator()(const cv::Range& range) const
{
for (int y(range.start); y < (range.end); ++y) {
uint8_t* D = result.data + result.step * y * 2;
uint8_t const* S = image.data + image.step * y;
for (int x(0); x < image.cols; ++x) {
D[x * 2] = S[x];
}
}
}
Timing:
Total = 3387.87 ms
Iteration = 13.2339 ms
FPS = 75.5636
You can use the Kronecker product of your image and a pattern like:
1, 0
0, 0
The result is:
Input:
[1, 2, 3;
4, 5, 6;
7, 8, 9]
Output:
[1, 0, 2, 0, 3, 0;
0, 0, 0, 0, 0, 0;
4, 0, 5, 0, 6, 0;
0, 0, 0, 0, 0, 0;
7, 0, 8, 0, 9, 0;
0, 0, 0, 0, 0, 0]
Code:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat1b kron(const Mat1b& A, const Mat1b& B)
{
Mat1b K(A.rows * B.rows, A.cols * B.cols, uchar(0));
for (int ra = 0; ra < A.rows; ++ra)
{
for (int ca = 0; ca < A.cols; ++ca)
{
K(Range(ra*B.rows, (ra + 1)*B.rows), Range(ca*B.cols, (ca + 1)*B.cols)) = B.mul(A(ra, ca));
}
}
return K;
}
int main()
{
Mat1b img = (Mat1b(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
std::cout << "Input:\n" << img << "\n\n";
// Define the pattern
Mat1b pattern = (Mat1b(2, 2) << 1, 0,
0, 0);
Mat1b out = kron(img, pattern);
std::cout << "Output:\n" << out << "\n\n";
return 0;
}
OpenCV doesn't have the Kronecker product implemented, so you need to write a custom function. For a more general implementation that works with all data types (1 channel) have a look here.
I found that #Dan Masek approach is faster. This is because my kron implementation is not optimized. I expect this approach to work pretty well with a good implementation.
Thought of sharing the following approach as it is a bit different. I don't know how efficient this would be compared to other methods. At least you can use opencv calls without any looping and easily use arbitrary scale factors for x and y.
First convert your image to floating point type, then scale it using warpAffine (use linear interpolation). Resize the same image using nearest-neighbor method. Compare the two resulting images element-wise to get a mask. Use this mask to copy the relevant elements from any of the result images.
Here's the code and some results I get:
uchar data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Mat im(3, 3, CV_8U, data);
im.convertTo(im, CV_32F);
// x and y scale
int xscale = 2, yscale = 2;
Size size(im.cols * xscale, im.rows * yscale);
float tr[] = {xscale, 0, 0, 0, yscale, 0};
Mat m(2, 3, CV_32F, tr); // transformation matrix
Mat resized1, resized2;
warpAffine(im, resized1, m, size); // affine scaling with linear interpolation
resize(im, resized2, size, 0, 0, INTER_NEAREST); // resize with nearest neighbor
// get the mask
Mat resized = resized1 == resized2;
// copy the pixels
resized1.copyTo(resized, resized);
cout << "image:\n" << im << endl;
cout << "M:\n" << m << endl;
cout << "affine(scaled):\n" << resized1 << endl;
cout << "resized:\n" << resized2 << endl;
cout << "mask:\n" << resized << endl;
cout << "output:\n" << resized << endl;
For xscale = 2, yscale = 2
image:
[1, 2, 3;
4, 5, 6;
7, 8, 9]
M:
[2, 0, 0;
0, 2, 0]
affine(scaled):
[1, 1.5, 2, 2.5, 3, 1.5;
2.5, 3, 3.5, 4, 4.5, 2.25;
4, 4.5, 5, 5.5, 6, 3;
5.5, 6, 6.5, 7, 7.5, 3.75;
7, 7.5, 8, 8.5, 9, 4.5;
3.5, 3.75, 4, 4.25, 4.5, 2.25]
resized:
[1, 1, 2, 2, 3, 3;
1, 1, 2, 2, 3, 3;
4, 4, 5, 5, 6, 6;
4, 4, 5, 5, 6, 6;
7, 7, 8, 8, 9, 9;
7, 7, 8, 8, 9, 9]
mask:
[1, 0, 2, 0, 3, 0;
0, 0, 0, 0, 0, 0;
4, 0, 5, 0, 6, 0;
0, 0, 0, 0, 0, 0;
7, 0, 8, 0, 9, 0;
0, 0, 0, 0, 0, 0]
output:
[1, 0, 2, 0, 3, 0;
0, 0, 0, 0, 0, 0;
4, 0, 5, 0, 6, 0;
0, 0, 0, 0, 0, 0;
7, 0, 8, 0, 9, 0;
0, 0, 0, 0, 0, 0]
For xscale = 4, yscale = 3
output:
[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
How can I access a global table that already exists in Lua using C++ ?
Below are code which I tried. I tried creating a global variable and try modifying a that local to the local in Lua but things dont seem to work
lua_State *lua_state = luaL_newstate();
luaL_openlibs(lua_state);
// lua_createtable(lua_state, 0, 81);
// for (int i = 1; i <= 81; i++)
// {
// lua_pushnumber(lua_state, i);
// lua_pushnumber(lua_state, grid_[i - 1]);
// lua_settable(lua_state, -3);
// }
//
// lua_setglobal(lua_state, "arg");
// lua_createtable(lua_state, 81, 1);
//
// for (int i = 1; i <= 81; i++)
// {
// lua_pushnumber(lua_state, i);
// lua_pushnumber(lua_state, grid_[i - 1]);
// lua_settable(lua_state, -3);
// }
// lua_setglobal(lua_state, "arg");
luaL_loadfile(lua_state, "main.lua");
lua_call(lua_state, 0, 0);
int t = 2;
/* table is in the stack at index 't' */
lua_pushnil(lua_state); /* first key */
while (lua_next(lua_state, t) != 0) {
/* uses 'key' (at index -2) and 'value' (at index -1) */
printf("%s - %s\n",
lua_typename(lua_state, lua_type(lua_state, -2)),
lua_typename(lua_state, lua_type(lua_state, -1)));
/* removes 'value'; keeps 'key' for next iteration */
lua_pop(lua_state, 1);
}
Lua
problem =
{
{9, 0, 0, 1, 0, 0, 0, 0, 5},
{0, 0, 5, 0, 9, 0, 2, 0, 1},
{8, 0, 0, 0, 4, 0, 0, 0, 0},
{0, 0, 0, 0, 8, 0, 0, 0, 0},
{0, 0, 0, 7, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 2, 6, 0, 0, 9},
{2, 0, 0, 3, 0, 0, 0, 0, 6},
{0, 0, 0, 2, 0, 0, 9, 0, 0},
{0, 0, 1, 9, 0, 4, 5, 7, 0},
}
Update 1
int main()
{
lua_State *lua_state = luaL_newstate();
luaL_openlibs(lua_state);
luaL_loadfile(lua_state, "main.lua");
lua_getglobal(lua_state, "problem");
//lua_pushglobaltable(lua_state); // Get global table
lua_pushnil(lua_state); // put a nil key on stack
while (lua_next(lua_state, -2) != 0) { // key(-1) is replaced by the next key(-1) in table(-2)
std::string name = lua_tostring(lua_state, -2); // Get key(-2) name
std::cout << name << std::endl;
lua_pop(lua_state, 1); // remove value(-1), now key on top at(-1)
}
lua_pop(lua_state, 1); // remove global table(-1)
lua_call(lua_state, 0, 0);
return 0;
}
Lua
problem =
{
{9, 0, 0, 1, 0, 0, 0, 0, 5},
{0, 0, 5, 0, 9, 0, 2, 0, 1},
{8, 0, 0, 0, 4, 0, 0, 0, 0},
{0, 0, 0, 0, 8, 0, 0, 0, 0},
{0, 0, 0, 7, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 2, 6, 0, 0, 9},
{2, 0, 0, 3, 0, 0, 0, 0, 6},
{0, 0, 0, 2, 0, 0, 9, 0, 0},
{0, 0, 1, 9, 0, 4, 5, 7, 0},
}
print("Lua Works")
user_input = io.read();
You don't have any values to iterate on Lua stack.
That int t=2; doesn't reflect anything, and your script doesn't return values to be left on stack.
See PIL book: 25.1 – Table Manipulation for examples on accessing global table.
I need to check, whether a letter (in english and russian languages) is alphabetical. A file is supposed to be encoded with UTF-8 by default.
I found out, that the best solution is working with UCS codes.
The way to calculate UCS-code of 2-bytes encoded letter is
#include <stdio.h>
#include <stdlib.h>
char utf8len[256] = {
// len = utf8len[c] & 0x7 cont = utf8len[c] & 0x8
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 - 15
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 16 - 31
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 32 - 47
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 48 - 63
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 80 - 95
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 112 - 127
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 80 - 8f
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 90 - 9f
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // a0 - af
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // b0 - bf
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // c0 - cf
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // d0 - df
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // e0 - ef
4, 4, 4, 4, 4, 4, 4, 4, // f0 - f7
5, 5, 5, 5, // f8, f9, fa, fb
6, 6, // fc, fd
0, 0 // fe, ff
};
#define UTF8LEN(c) (utf8len[(unsigned char)(c)] & 0x7)
#define UTF8CONT(c) (utf8len[(unsigned char)(c)] & 0x8)
int main (int argc, char *argv[])
{
char *s = "Б№1АГД"; //string which contains cyrillic symbols
while (*s) {
int ucode;
printf ("[%s] %d\n", s, UTF8LEN(*s));
if ((UTF8LEN(*s) == 2) && UTF8CONT(s[1])) {
ucode = ((*s & 0x1f) << 6) | (s[1] & 0x3f); //! HERE I GET UCS CODE
printf ("ucode = 0x%x\n", ucode);
s++;
}
s++;
}
}
It's a half of the solution I'm looking for. This code alows me to work with cyrillic symbols only (as they're encoded with 2 bytes in UTF-8). The problem is, I need to work with latin alphabet as well.
So what should i do to get UCS code for 1-byte symbol (in my case with UTF8LEN(c)=1)?
Upd: Probably, the solution is:
ucode = *s
Will this work?
I have been staring at this code for few hours, tried walkthrough,debugging with autos and breakpoints and it's no solution so far. Maybie someone's fresh look would help me ;) .
#include <iostream>
using namespace std;
int matrix[9][9] = {{0, 0, 6, 0, 0, 0, 1, 0, 5},
{0, 4, 0, 7, 0, 6, 0, 3, 9},
{2, 0, 0, 9, 3, 0, 6, 0, 0},
{7, 0, 0, 1, 8, 0, 5, 0, 4},
{0, 0, 4, 0, 6, 0, 9, 0, 0},
{1, 0, 9, 0, 5, 2, 0, 0, 3},
{0, 0, 1, 0, 9, 3, 0, 0, 7},
{6, 7, 0, 5, 0, 8, 0, 9, 0},
{9, 0, 8, 0, 0, 0, 4, 0, 0}};
bool check(int column ,int row,int checkedValue)
{
//column check
for(int i=0; i<9; i++)
{
if(i==row)continue;
if(checkedValue==matrix[column][i]) return false;
}
//row check
for(int i=0; i<9; i++)
{
if(i==column) continue;
if(checkedValue==matrix[i][row]) return false;
}
return true;
}
int main()
{
cout<<check(4,0,4); //Why does it output 0? There is no "4" in the 5th column and the 1st row.
system("pause");
return 0;
}
The function check(column,row,value) was designed to return 0 when number occurs at least once in the "matrix" two dimensional table. This program is a chunk of sudoku solver.
You mixed the indices up in the if statements. They should be:
if(checkedValue==matrix[i][column]) return false; // not matrix[column][i]
and
if(checkedValue==matrix[row][i]) return false; // not matrix[i][row]
The reason is that the first dimension is the row. You can check this by printing matrix[2][0].
For your matrix, you will get 2 (and not 6).