Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong output of the ellipse detector in C++ #12

Open
IaBogdi opened this issue Oct 2, 2019 · 10 comments
Open

Wrong output of the ellipse detector in C++ #12

IaBogdi opened this issue Oct 2, 2019 · 10 comments

Comments

@IaBogdi
Copy link

IaBogdi commented Oct 2, 2019

Dear developer,

I attempted to change the code so it could run on C++. In file generateEllipseCandidates.cpp I replaced mexFunction by the following one:

void ellipse_detector(Mat& img, int edge_process_select, int specified_polarity, double* candidates_out, Mat& out_mat) {
	uchar * inputimg = img.data;
	int imgy, imgx;
	imgy = img.cols;
	imgx = img.rows;
	double *data = (double*)malloc(imgy*imgx * sizeof(double));
	for (int c = 0; c<imgx; c++)
	{
		for (int r = 0; r<imgy; r++)
		{
			data[c + r*imgx] = inputimg[r + c*imgy];
		}
	}
	int n;
	std::vector<std::vector<int> > groups;
	double * coverages;
	int * reg;
	int reg_x;
	int reg_y;
	double* out = mylsd(&n, data, imgx, imgy, &reg, &reg_x, &reg_y);
	groupLSs(out, n, reg, reg_x, reg_y, &groups);
	free(reg);
	calcuGroupCoverage(out, n, groups, coverages);

	printf("The number of output arc-support line segments: %i\n", n);
	printf("The number of arc-support groups:%i\n", groups.size());
	image_double angles;
	if (edge_process_select == 1)
		calculateGradient2(data, imgx, imgy, &angles); //version2, sobel; version 3 canny
	else
		calculateGradient3(data, imgx, imgy, &angles); //version2, sobel; version 3 canny
	PairGroupList * pairGroupList;
	double distance_tolerance = 2;
	printf("Tolerance: %f \n", distance_tolerance);
	double * candidates;
	int  candidates_num;//��ѡ��Բ����
							//rejectShortLines(out,n,&new_n);
	pairGroupList = getValidInitialEllipseSet(out, n, &groups, coverages, angles, distance_tolerance, specified_polarity);
	if (pairGroupList != NULL)
	{
		printf("The number of initial ellipses %i \n", pairGroupList->length);
		generateEllipseCandidates(pairGroupList, distance_tolerance, candidates, &candidates_num);
		printf("The number of ellipse candidates: %i \n", candidates_num);
		candidates_out = (double*) malloc(sizeof(double) * 5 * candidates_num);
		memcpy(candidates_out, candidates, sizeof(double) * 5 * candidates_num);
		//��ѡԲ���(xi,yi,ai,bi,phi_i)', 5 x candidates_num, ���Ƶ�����candidates_out��
		freePairGroupList(pairGroupList);
	}
	else
	{
		candidates_num = 0;
		printf("The number of initial ellipses %i \n", 0);
		candidates_out = (double*)malloc(5 * sizeof(double));
		candidates_out[0] = candidates_out[1] = candidates_out[2] = candidates_out[3] = candidates_out[4] = 0;
	}
	transpose(img, out_mat);
	for (int i = 0; i<n; i++)//draw lines
	{
		Point2d p1(out[8 * i], out[8 * i + 1]), p2(out[8 * i + 2], out[8 * i + 3]);
		line(out_mat, p1, p2, Scalar(255, 0, 0));
	}
	if (candidates_num > 0)//draw ellipses
	{
		for (int i = 0; i<candidates_num; i++)
			ellipse(out_mat, cv::Point((int)candidates_out[i * 5], (int)candidates_out[i * 5 + 1]), cv::Size(candidates_out[i * 5 + 2], candidates_out[i * 5 + 3]), candidates_out[i * 5 + 4] * 180 / M_PI, 0, 360, (Scalar(255, 0, 0)), 1);
	}
	free(data);
	free(coverages);
	free(out);
	free_image_double(angles);

}

and main.cpp is the following one:

#include "detector_core.h"


int main()
{
	Mat img = imread("13.jpg",IMREAD_GRAYSCALE);
	Mat out;
	double *ans = NULL;
	ellipse_detector(img, 1, -1, ans, out);
	transpose(out, out);
	imwrite("output.jpg",out);
	free(ans);
	waitKey(0);
	return 0;
}

detector_core.h is a code of your detector where I put your code with the ellipse_detector function.

It works so that it detects arc-support lines, combines them into groups but it cannot find initial ellipses and hence no output ellipses, only arcs which look quite reliable.

output

How to fix it so it could provide ellipses?

@Kakashi4
Copy link

Hey, could you share the entire C++ code so I could have a look at it?

@IaBogdi
Copy link
Author

IaBogdi commented Nov 18, 2019

Sure ;)

main.cpp
https://pastebin.com/i0AM1njk

detector_core.h :
https://pastebin.com/kWDp1LDE

@Kakashi4
Copy link

Thank you so much, I'll look through it

@Kakashi4
Copy link

Hey, I'm having a few problems getting the lapacke header files to be recognized by my visual studio, do you have any idea about it? I already added the lapacke libraries and dlls to my project.

@MrYaoLIng
Copy link

Hi, IaBogdi, Do you have solved the above problem ?

@OnofreMartorell
Copy link

Hi, @IaBogdi , did you manage to solve the problem of not detecting any ellipse?

@xiahaa
Copy link

xiahaa commented May 20, 2020

Dear developer,

I attempted to change the code so it could run on C++. In file generateEllipseCandidates.cpp I replaced mexFunction by the following one:

void ellipse_detector(Mat& img, int edge_process_select, int specified_polarity, double* candidates_out, Mat& out_mat) {
	uchar * inputimg = img.data;
	int imgy, imgx;
	imgy = img.cols;
	imgx = img.rows;
	double *data = (double*)malloc(imgy*imgx * sizeof(double));
	for (int c = 0; c<imgx; c++)
	{
		for (int r = 0; r<imgy; r++)
		{
			data[c + r*imgx] = inputimg[r + c*imgy];
		}
	}
	int n;
	std::vector<std::vector<int> > groups;
	double * coverages;
	int * reg;
	int reg_x;
	int reg_y;
	double* out = mylsd(&n, data, imgx, imgy, &reg, &reg_x, &reg_y);
	groupLSs(out, n, reg, reg_x, reg_y, &groups);
	free(reg);
	calcuGroupCoverage(out, n, groups, coverages);

	printf("The number of output arc-support line segments: %i\n", n);
	printf("The number of arc-support groups:%i\n", groups.size());
	image_double angles;
	if (edge_process_select == 1)
		calculateGradient2(data, imgx, imgy, &angles); //version2, sobel; version 3 canny
	else
		calculateGradient3(data, imgx, imgy, &angles); //version2, sobel; version 3 canny
	PairGroupList * pairGroupList;
	double distance_tolerance = 2;
	printf("Tolerance: %f \n", distance_tolerance);
	double * candidates;
	int  candidates_num;//��ѡ��Բ����
							//rejectShortLines(out,n,&new_n);
	pairGroupList = getValidInitialEllipseSet(out, n, &groups, coverages, angles, distance_tolerance, specified_polarity);
	if (pairGroupList != NULL)
	{
		printf("The number of initial ellipses %i \n", pairGroupList->length);
		generateEllipseCandidates(pairGroupList, distance_tolerance, candidates, &candidates_num);
		printf("The number of ellipse candidates: %i \n", candidates_num);
		candidates_out = (double*) malloc(sizeof(double) * 5 * candidates_num);
		memcpy(candidates_out, candidates, sizeof(double) * 5 * candidates_num);
		//��ѡԲ���(xi,yi,ai,bi,phi_i)', 5 x candidates_num, ���Ƶ�����candidates_out��
		freePairGroupList(pairGroupList);
	}
	else
	{
		candidates_num = 0;
		printf("The number of initial ellipses %i \n", 0);
		candidates_out = (double*)malloc(5 * sizeof(double));
		candidates_out[0] = candidates_out[1] = candidates_out[2] = candidates_out[3] = candidates_out[4] = 0;
	}
	transpose(img, out_mat);
	for (int i = 0; i<n; i++)//draw lines
	{
		Point2d p1(out[8 * i], out[8 * i + 1]), p2(out[8 * i + 2], out[8 * i + 3]);
		line(out_mat, p1, p2, Scalar(255, 0, 0));
	}
	if (candidates_num > 0)//draw ellipses
	{
		for (int i = 0; i<candidates_num; i++)
			ellipse(out_mat, cv::Point((int)candidates_out[i * 5], (int)candidates_out[i * 5 + 1]), cv::Size(candidates_out[i * 5 + 2], candidates_out[i * 5 + 3]), candidates_out[i * 5 + 4] * 180 / M_PI, 0, 360, (Scalar(255, 0, 0)), 1);
	}
	free(data);
	free(coverages);
	free(out);
	free_image_double(angles);

}

and main.cpp is the following one:

#include "detector_core.h"


int main()
{
	Mat img = imread("13.jpg",IMREAD_GRAYSCALE);
	Mat out;
	double *ans = NULL;
	ellipse_detector(img, 1, -1, ans, out);
	transpose(out, out);
	imwrite("output.jpg",out);
	free(ans);
	waitKey(0);
	return 0;
}

detector_core.h is a code of your detector where I put your code with the ellipse_detector function.

It works so that it detects arc-support lines, combines them into groups but it cannot find initial ellipses and hence no output ellipses, only arcs which look quite reliable.

output

How to fix it so it could provide ellipses?

Could be the lapack you link to the program. I tried with lapack (failure, just like you, no initial ellipses), mwlapack (lapack with matlab) this one works, lapack from veclib of macos (works).

@mmueller-kaffeeschluerfercom

@IaBogdi The pastebin links are dead. Can you upload your code again? Thanks!

@Mickeyyyang
Copy link

Dear developer,

I attempted to change the code so it could run on C++. In file generateEllipseCandidates.cpp I replaced mexFunction by the following one:

void ellipse_detector(Mat& img, int edge_process_select, int specified_polarity, double* candidates_out, Mat& out_mat) {
	uchar * inputimg = img.data;
	int imgy, imgx;
	imgy = img.cols;
	imgx = img.rows;
	double *data = (double*)malloc(imgy*imgx * sizeof(double));
	for (int c = 0; c<imgx; c++)
	{
		for (int r = 0; r<imgy; r++)
		{
			data[c + r*imgx] = inputimg[r + c*imgy];
		}
	}
	int n;
	std::vector<std::vector<int> > groups;
	double * coverages;
	int * reg;
	int reg_x;
	int reg_y;
	double* out = mylsd(&n, data, imgx, imgy, &reg, &reg_x, &reg_y);
	groupLSs(out, n, reg, reg_x, reg_y, &groups);
	free(reg);
	calcuGroupCoverage(out, n, groups, coverages);

	printf("The number of output arc-support line segments: %i\n", n);
	printf("The number of arc-support groups:%i\n", groups.size());
	image_double angles;
	if (edge_process_select == 1)
		calculateGradient2(data, imgx, imgy, &angles); //version2, sobel; version 3 canny
	else
		calculateGradient3(data, imgx, imgy, &angles); //version2, sobel; version 3 canny
	PairGroupList * pairGroupList;
	double distance_tolerance = 2;
	printf("Tolerance: %f \n", distance_tolerance);
	double * candidates;
	int  candidates_num;//��ѡ��Բ����
							//rejectShortLines(out,n,&new_n);
	pairGroupList = getValidInitialEllipseSet(out, n, &groups, coverages, angles, distance_tolerance, specified_polarity);
	if (pairGroupList != NULL)
	{
		printf("The number of initial ellipses %i \n", pairGroupList->length);
		generateEllipseCandidates(pairGroupList, distance_tolerance, candidates, &candidates_num);
		printf("The number of ellipse candidates: %i \n", candidates_num);
		candidates_out = (double*) malloc(sizeof(double) * 5 * candidates_num);
		memcpy(candidates_out, candidates, sizeof(double) * 5 * candidates_num);
		//��ѡԲ���(xi,yi,ai,bi,phi_i)', 5 x candidates_num, ���Ƶ�����candidates_out��
		freePairGroupList(pairGroupList);
	}
	else
	{
		candidates_num = 0;
		printf("The number of initial ellipses %i \n", 0);
		candidates_out = (double*)malloc(5 * sizeof(double));
		candidates_out[0] = candidates_out[1] = candidates_out[2] = candidates_out[3] = candidates_out[4] = 0;
	}
	transpose(img, out_mat);
	for (int i = 0; i<n; i++)//draw lines
	{
		Point2d p1(out[8 * i], out[8 * i + 1]), p2(out[8 * i + 2], out[8 * i + 3]);
		line(out_mat, p1, p2, Scalar(255, 0, 0));
	}
	if (candidates_num > 0)//draw ellipses
	{
		for (int i = 0; i<candidates_num; i++)
			ellipse(out_mat, cv::Point((int)candidates_out[i * 5], (int)candidates_out[i * 5 + 1]), cv::Size(candidates_out[i * 5 + 2], candidates_out[i * 5 + 3]), candidates_out[i * 5 + 4] * 180 / M_PI, 0, 360, (Scalar(255, 0, 0)), 1);
	}
	free(data);
	free(coverages);
	free(out);
	free_image_double(angles);

}

and main.cpp is the following one:

#include "detector_core.h"


int main()
{
	Mat img = imread("13.jpg",IMREAD_GRAYSCALE);
	Mat out;
	double *ans = NULL;
	ellipse_detector(img, 1, -1, ans, out);
	transpose(out, out);
	imwrite("output.jpg",out);
	free(ans);
	waitKey(0);
	return 0;
}

detector_core.h is a code of your detector where I put your code with the ellipse_detector function.

It works so that it detects arc-support lines, combines them into groups but it cannot find initial ellipses and hence no output ellipses, only arcs which look quite reliable.

output

How to fix it so it could provide ellipses?

Hi, My dear friend~
Can I get your C++ code about it now?

@xiahaa
Copy link

xiahaa commented May 6, 2022

@IaBogdi
Finally, I think I get the cause.
If anybody is using LAPACKE, then the following line of code is NOT correct:
LAPACKE_dggev(xxxx)
It should not be ROW_MAJOR, but COL_MAJOR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants