meshgrid matlab to c++ different results - c++

here is the matlab code i'm trying to convert to c++
where
size(Iorig) == 1334X 2026
%% label checkers
Label = zeros(size(Iorig));
Margins = 11;
[X,Y] = meshgrid(1:size(Iorig,2),1:size(Iorig,1));
k = 1;
for i = 1:4
for j = 1:6
rr = rect{i,j};
x1 = rr(1);
x2 = rr(1) + rr(3);
y1 = rr(2);
y2 = rr(2) + rr(4);
Label(X>=x1+Margins&X<x2-Margins&Y>=y1+Margins&Y<y2-Margins) = k;
k = k+1;
end
end
I understand that we want to label the rectangles which are found in the previous step, there are 24 of those.
but I don't understand how to convert this line into easy c++ code without allocating a huge buffer of X and Y which basically just holds... indices..
thanks for your help here is what i started doing.
//label Checkers
List<List<int>^>^ label = gcnew List<List<int>^>();
int margins = 11;
int k = 1;
for (size_t i = 0; i < 4; i++)
{
for (size_t j = 0; j < 6; j++)
{
MacbethCheckerBatchesColor^ rect = autoDetectMacbethResult[i * 6 + j];
Point^ r = rect->Points[0];
int x1 = r->X;
int y1 = r->Y;
r = rect->Points[2];
int x2 = r->X;
int y2 = r->Y;
for (int h = 0; h < inputImage->HeightLines; h++)
{
List<int>^ tempRow = gcnew List<int>();
for (int w = 0; w < inputImage->WidthColumns; w++)
{
if ( (w>= x1+margins) & (w<x2-margins) & (h >= y1+margins) & (h<y2-margins) )
{
tempRow->Add(k);
}
else
{
tempRow->Add(0);
}
}
label->Add(tempRow);
}
k= k+100;//i tried here many other numbers... same result
}
}
Here is my result can you please help me find my mistake, the rectangles are the same, I guesss I have some other logical mistake.

Related

Receive values from dynamic array

I recently asked question about how to work with element Edit1 dynamically, now I want to ask something about values, which I received from dynamical arrays. First I try to divide image into sectors:
const n=20;
unsigned short i, j, line_length, w = Image1->Width, h = Image1->Height, l = Left + Image1->Left, t = Top + Image1->Top;
unsigned short border = (Width-ClientWidth)/2, topborder = Height-ClientHeight-border;
Image1->Canvas->Pen->Color = clRed;
for (i = 0; i <= n; i++)
{
Image1->Canvas->MoveTo(0, 0);
line_length = w * tan(M_PI/2*i/n);
if (line_length <= h)
Image1->Canvas->LineTo(w, line_length);
else
{
line_length = h * tan(M_PI/2*(1-1.*i/n));
Image1->Canvas->LineTo(line_length, h);
}
}
Then I use regions to count black dots in each sector and I want to add values to element Memo:
HRGN region[n];
TPoint points[3];
points[0] = Point(l + border, t + topborder);
for (i = 0; i < n; i++)
{
for (j = 0; j <= 1; j++)
{
line_length = w * tan(M_PI/2*(i+j)/n);
if (line_length <= h)
points[j+1] = Point(l + border + w, t + topborder + line_length);
else
{
line_length = h * tan(M_PI/2*(1-1.*(i+j)/n));
points[j+1] = Point(l + border + line_length, t + topborder + h);
}
}
region[i] = CreatePolygonRgn(points, 3, ALTERNATE); // or WINDING ?? as u want
}
Byte k;
unsigned __int64 point_count[n] = {0}, points_count = 0;
for(j = 0; j < h; j++)
for (i = 0; i < w; i++)
if (Image1->Canvas->Pixels[i][j] == clBlack)
{
points_count++;
for (k = 0; k < n; k++)
if (PtInRegion(region[k], l + border + i, t + topborder + j))
point_count[k]++;
}
unsigned __int64 sum = 0;
for (i = 0; i < n; i++)
{
sum += point_count[i];
Memo1->Lines->Add(point_count[i]);
}
As i received an advice from one man, in order to allocate an array using a TEdit to specify the array's count I should use, for example DynamicArray:
#include <sysdyn.h>
DynamicArray<HRGN> region;
...
int n = Edit1-> Text.ToInt();
region.Length = n;
I have made the same changes to point_count array:
Byte k;
DynamicArray<unsigned __int64> point_count;
point_count.Length = n;
unsigned __int64 /*point_count[n] = {0},*/ points_count = 0;
...
The problem is that I received different values if I do it dynamically or statically(n=20).
Statically:
Dynamically:
The problem is that I received different values if I do it dynamically or statically(n=20)
There is no difference whatsoever in accessing elements of a static array vs a dynamic array. Your problem has to be elsewhere.
For instance, your static code is initializing all of the array elements to 0, but your dynamic code is not doing that, so they will have random values before your loop then increments them.
Try this:
DynamicArray<unsigned __int64> point_count;
point_count.Length = n;
for(int i = 0; i < n; ++i) {
point_count[i] = 0;
}
...
Alternatively:
DynamicArray<unsigned __int64> point_count;
point_count.Length = n;
ZeroMemory(&point_count[0], sizeof(unsigned __int64) * n);
...
Also, using the Image1->Canvas->Pixels[][] property is very slow. Consider using the Image1->Picture->Bitmap->ScanLine[] property instead for faster access to the raw pixels.

Eigen multiplication assertion failed

I have 2 MatrixXd that I want to multiply. But I get a runtime error.
Assertion failed: lhs.cols() == rhs.rows() && "invalid matrix product" && "if you wanted a coeff-wise or a dot product use the respective explicit functions",
file C:\Users\<myPathToProject>\packages\Eigen.3.3.3\build\native\include\Eigen\src\Core\Product.h, line 97
I've checked the size of both matrices and I should be able to multiply them together, or maybe my maths skills are wrong. Here are the content of my two MatrixXd:
Matrix A:
1 1 1 1 1 1
0.0196078 0 1 1 0.184314 0.329412
Matrix B:
1
1
-1
-1
-1
-1
Here is the code to reproduce. W and YTrain are double*:
double* W = (double*)malloc(sizeof(double) * 2);
double* YTrain = (double*)malloc(sizeof(double) * 6);
double* XTrain = (double*)malloc(sizeof(double) * 6);
W[0] = -0.527407;
W[1] = -0.0828247;
XTrain[0] = 0.0196078;
XTrain[1] = 0;
XTrain[2] = 1;
XTrain[3] = 1;
XTrain[4] = 0.184314;
XTrain[5] = 0.329412;
YTrain[0] = 1;
YTrain[1] = 1;
YTrain[2] = -1;
YTrain[3] = -1;
YTrain[4] = -1;
YTrain[5] = -1;
Eigen::MatrixXd mat_Y(6, 1);
for (int i = 0; i < 6; i++)
mat_Y(i) = YTrain[i];
Eigen::MatrixXd mat_XTrain(2, 6);
int pos = 0;
for (int x = 0; x < 6; x++)
{
for (int y = 0; y < 1; y++)
{
if (y == 0)
mat_XTrain(y, x) = 1;
else
{
mat_XTrain(y, x) = XTrain[pos];
pos++;
}
}
}
Eigen::MatrixXd mult = mat_XTrain.transpose() * mat_XTrain;
auto pseudo_inv = mult.completeOrthogonalDecomposition().pseudoInverse();
Eigen::MatrixXd mult_trans = pseudo_inv * mat_XTrain.transpose();
auto final_res = mult_trans * mat_Y;
Indeed the maths was impossible to multiply a 6x2 matrix with a 1x6.
With help of Matthew M. I've released my algorithm was bad. I've added a row to XTrain, but I didn't need it.
To recap, XTrain was wrong dimension.

Code optimization of Bilinear interpolation

I have implemented bilinear interpolation algorithm according to the MATLAB example:
https://se.mathworks.com/matlabcentral/fileexchange/10772-fast-2-dimensional-interpolation; https://en.wikipedia.org/wiki/Bilinear_interpolation - Unit square formula.
Would be great to speed up the implementation. Can somebody give me suggestions how to optimize the code for speeding it up? Please, find part of the method:
x_loops = floor((X_end-X_11)/pixel_size_mm)+1;
y_loops = floor((Y_end-Y_11)/pixel_size_mm)+1;
float** Zi = new float*[x_loops] ();
for(int i = 0; i < x_loops; ++i)
Zi[i] = new float[y_loops] ();
n_dx = 1/(X_12 - X_11);
n_dy = 1/(Y_21 - Y_11);
Yi = Y_11;
int count = 0;
for(int i = 0; i < y_loops; i++)
{
Xi = X_11;
xi = 0;
yi = 0;
for(int j = 0; j < x_loops; j++)
{
xi = (Xi - X_11)*n_dx;
yi = (Yi - Y_11)*n_dy;
Xi += pixel_size_mm;
fxi = floor(xi);
fyi = floor(yi);
dfxi = xi - fxi;
dfyi = yi - fyi;
Zi[j][i] = (Strain_image[fxi][fyi]*(1 - dfxi)*(1-dfyi) +
Strain_image[fxi+1][fyi]*dfxi*(1-dfyi) + Strain_image[fxi][fyi+1]*
(1-dfxi)*dfyi + Strain_image[fxi+1][fyi+1]*dfxi*dfyi);
}
Yi += pixel_size_mm;
}
iMage(Zi, x_loops, y_loops,fX1,fY1);
for(int i = 0; i < x_loops; ++i)
delete [] Zi[i];
delete[] Zi;
for(int i = 0; i < number_of_RF_rows; ++i)
delete [] Strain_image[i];
delete[] Strain_image;

Seeded region growing OpenCV

I am using Win 7,64, MS2012(C++) and OpenCV 2.4.11
I write seeded region growing algorithm but I down't know why the results not desired.
The goal is that extract pectoral muscle(left corner) of image with SRG algorithm.
input image :
here is my code (main function)
img = imread("C:/Users/Zimabi/Downloads/region_growing/jhgray.jpg",0);
Mat J1 = Mat::zeros(img.rows,img.cols,CV_8UC1);
int x=15,y=15;
int reg_mean = img.at<uchar>(x,y);
int reg_size = 1;
int neg_pos = 0;
Mat neg_list = Mat::zeros(img.cols*img.rows,3,CV_8UC1);
double pixdist = 0, reg_maxdist = 0.1;
int xn = 0,yn = 0;
Mat neigb = Mat::zeros(4,2,CV_8UC1);
int nei1 [4] = {-1,1,0,0};
int nei2 [4] = {0,0,-1,1};
while ((pixdist < reg_maxdist) && (reg_size < img.cols*img.rows))
{
int inx,min1=1000;
for (int r = 0; r < 4; r++)
{
xn = x + nei1[r] ;
yn = y + nei2[r];
bool ins=(xn>=1)&&(yn>=1)&&(xn<=img.rows)&&(yn<= img.cols);
if (ins && (J1.at<uchar>(xn,yn) == 0))
{
neg_pos = neg_pos+1;
neg_list.at<uchar>(neg_pos,0) = xn;
neg_list.at<uchar>(neg_pos,1) = yn;
neg_list.at<uchar>(neg_pos,2) = img.at<uchar>(xn,yn);
J1.at<uchar>(xn,yn)=255;
}
}
Mat x1 = Mat::zeros(neg_pos,1,CV_8UC1);
for (int i3 = 0; i3 <neg_pos ; i3++)
{
x1.at<uchar>(i3,0) = abs(neg_list.at<uchar>(i3,2) - reg_mean);
if (x1.at<uchar>(i3,0)<min1)
{
min1 = x1.at<uchar>(i3,0);
inx = i3;
}
}
pixdist = min1;
J1.at<uchar>(x,y)=255;
reg_size=reg_size+1;
reg_mean= (reg_mean*reg_size + neg_list.at<uchar> (inx,2))/(reg_size+1);
x = neg_list.at<uchar>(inx,0);
y = neg_list.at<uchar>(inx,1);
neg_list.at<uchar>(inx,0) = neg_list.at<uchar>(neg_pos,0);
neg_list.at<uchar>(inx,1) = neg_list.at<uchar>(neg_pos,1);
neg_list.at<uchar>(inx,2) = neg_list.at<uchar>(neg_pos,2);
neg_pos=neg_pos-1;
}
imshow("J",J1);
waitKey(0);
return 0;
Regards

From mathematic function to c++ code

I am trying to implement this F(S) function:
bellow is my code but is not working:
double EnergyFunction::evaluate(vector<short> field) {
double e = 0.0;
for (int k = 1; k < field.size() - 1; k++){
double c = 0.0;
for (int i = 1; i < field.size() - k; i++) {
c += field[i] * field[i + k];
}
e += pow(c, 2);
}
double f = pow(field.size(), 2) / ( 2 * e );
return f;
}
For example F(S) function should return value 8644 for vector:
1,1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,1
I need another par of eyes to look at my code because I am a bit lost here. :)
after refactoring:
double EnergyFunction::evaluate(vector<short> field) {
double e = 0.0;
int l = field.size()
for (int k = 1; k < l; k++){
double c = 0.0;
for (int i = 0, j = k; j < l; i++, j++) {
c += field[i] * field[j];
}
e += c*c;
}
return l*l / ( e+e );
}
explanation:
1. we need to iterate (L-1) times
2. we need to shift the base and offset indexes until we reach the last one
3. c*c and e+e are quicker and easier to read
You are mapping variables into different ranges using the same names, which is always going to be confusing. Better is to keep ranges and names the same as in the math, and only subtract one for 0-base indexes at indexing time. Also might as well use L explicitly:
int L = field.size();
for (int k = 1; k <= L-1; k++){
...
for (int i = 1; i <= L-k; i++) {
c += field[i -1] * field[i+k -1];
...