High-quality-ellipse-detection
                                
                                 High-quality-ellipse-detection copied to clipboard
                                
                                    High-quality-ellipse-detection copied to clipboard
                            
                            
                            
                        Wrong output of the ellipse detector in C++
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, ®, ®_x, ®_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.

How to fix it so it could provide ellipses?
Hey, could you share the entire C++ code so I could have a look at it?
Sure ;)
main.cpp https://pastebin.com/i0AM1njk
detector_core.h : https://pastebin.com/kWDp1LDE
Thank you so much, I'll look through it
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.
Hi, IaBogdi, Do you have solved the above problem ?
Hi, @IaBogdi , did you manage to solve the problem of not detecting any ellipse?
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, ®, ®_x, ®_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.
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).
@IaBogdi The pastebin links are dead. Can you upload your code again? Thanks!
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, ®, ®_x, ®_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.
How to fix it so it could provide ellipses?
Hi, My dear friend~ Can I get your C++ code about it now?
@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.