有部分程序看不懂,是关于最小二乘法拟合圆的,大神解释下呗
opencv吧
全部回复
仅看楼主
level 5
UINT CheckCircleOverlap( cv::Mat& img, cv::Point center, int radius, UINT &overlap_num, int shift = 0 )
{
CV_Assert( radius >= 0 && 0 <= shift && shift <= XY_SHIFT );
cv::Size size = img.size();
size_t step = img.step;
int pix_size = (int)img.elemSize();
uchar* ptr = img.data;
int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1;
int inside = center.x >= radius && center.x < size.width - radius &&
center.y >= radius && center.y < size.height - radius;
UINT total_num=0;
overlap_num=0;
#define ICV_COUNT_POINT( ptr, x )if( *(ptr + (x)*pix_size) ){overlap_num++;total_num++;}else{total_num++;}
while( dx >= dy )
{
int mask;
int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx;
int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy;
if( inside )
{
uchar *tptr0 = ptr + y11 * step;
uchar *tptr1 = ptr + y12 * step;
ICV_COUNT_POINT( tptr0, x11 );
ICV_COUNT_POINT( tptr1, x11 );
ICV_COUNT_POINT( tptr0, x12 );
ICV_COUNT_POINT( tptr1, x12 );
tptr0 = ptr + y21 * step;
tptr1 = ptr + y22 * step;
ICV_COUNT_POINT( tptr0, x21 );
ICV_COUNT_POINT( tptr1, x21 );
ICV_COUNT_POINT( tptr0, x22 );
}
else if( x11 < size.width && x12 >= 0 && y21 < size.height && y22 >= 0 )
{
if( (unsigned)y11 < (unsigned)size.height )
{
uchar *tptr = ptr + y11 * step;
if( x11 >= 0 )
ICV_COUNT_POINT( tptr, x11 );
if( x12 < size.width )
ICV_COUNT_POINT( tptr, x12 );
}
if( (unsigned)y12 < (unsigned)size.height )
{
uchar *tptr = ptr + y12 * step;
if( x11 >= 0 )
ICV_COUNT_POINT( tptr, x11 );
if( x12 < size.width )
ICV_COUNT_POINT( tptr, x12 );
}
if( x21 < size.width && x22 >= 0 )
{
if( (unsigned)y21 < (unsigned)size.height )
{
uchar *tptr = ptr + y21 * step;
if( x21 >= 0 )
ICV_COUNT_POINT( tptr, x21 );
if( x22 < size.width )
ICV_COUNT_POINT( tptr, x22 );
}
if( (unsigned)y22 < (unsigned)size.height )
{
uchar *tptr = ptr + y22 * step;
if( x21 >= 0 )
ICV_COUNT_POINT( tptr, x21 );
if( x22 < size.width )
ICV_COUNT_POINT( tptr, x22 );
}
}
}
dy++;
err += plus;
plus += 2;
mask = (err <= 0) - 1;
err -= minus & mask;
dx += mask;
minus -= mask & 2;
}
#undef ICV_COUNT_POINT
return total_num;
}
//1,1,
//183,332,10,68,73
//,0.5
void ExtendCV::FindCircles( cv::InputArray _image, cv::vector<circle_found>& _circles,
cv::vector<circle_found>& single_circles,
float dp, int min_dist,
int low_threshold, int high_threshold,int acc_threshold,int minRadius, int maxRadius,
float minScore, cv::InputArray _contour_image )
{
cv::Ptr<CvMemStorage> storage = cvCreateMemStorage(STORAGE_SIZE);
cv::Mat image = _image.getMat();
if (image.channels()!=1)
{
cv::cvtColor(image,image,CV_BGR2GRAY);
}
CvMat c_image = image;
cv::Mat contour_image = _contour_image.getMat();
cv::vector<cv::Vec3f> circles_all;
CvSeq* seq = cvFindCircles( &c_image, contour_image, storage, dp, min_dist, low_threshold, high_threshold,
acc_threshold, minRadius,maxRadius );
seqToMat(seq, circles_all);
std::vector<std::vector<cv::Point>> contours;
findContours(contour_image,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
drawContours(contour_image,contours,-1,cv::Scalar(255),overlap_check_brush);
/*imshow("轮廓图",contour_image);
cvWaitKey(0);*/
/*imwrite("轮廓图",contour_image);*/
// Mat draw_mat=Mat(contour_image.rows,contour_image.cols,CV_8UC1);
UINT NonZeroCount_circle,NonZeroCount_overlap;
float overlap_score=0;
_circles.clear();
int vector_size=circles_all.size();
int sd=circles_all[1][0];
for (int i=0,j=0;i<vector_size;i++)
{
NonZeroCount_circle=CheckCircleOverlap(contour_image,
cv::Point(circles_all[i][0],circles_all[i][1]),circles_all[i][2],NonZeroCount_overlap);
overlap_score=(float)NonZeroCount_overlap/(float)NonZeroCount_circle;
if (overlap_score>minScore)
{
_circles.push_back(circle_found());
_circles[j].score=overlap_score;
_circles[j].circle=circles_all[i];
j++;//分开计数,i记录的是比对过的总数,j记录的是比对后可以通过的计数
}
}
cv::vector<vector<circle_found>>circleVV;
std::sort(_circles.begin(),_circles.end(),SortCircleFound);
CombineSamePoint(_circles,circleVV);
for (int i=0;i<circleVV.size();i++)
{
single_circles.push_back(circleVV[i][0]);
}
}
float ExtendCV::DistPoint2D32f(CvPoint2D32f pt1, CvPoint2D32f pt2)
{
return sqrt((pt1.x-pt2.x)*(pt1.x-pt2.x)+(pt1.y-pt2.y)*(pt1.y-pt2.y));
}
void ExtendCV::CombineSamePoint( cv::vector<circle_found>& _circles,cv::vector<vector<circle_found>>&circleVV)
{
//合并相同点
//circleVV.push_back(vector<circle_found>(1, _circles[0]));
ofstream outfile;
outfile.open("circlessingle.txt",ios::out);
while(_circles.size()>1)
{
vector<circle_found>tmp_circles;
pickSame(_circles,tmp_circles);
std::sort(tmp_circles.begin(),tmp_circles.end(),SortCircleFound);
circleVV.push_back(tmp_circles);
for (int i=0;i<tmp_circles.size();i++)
{
//outfile<<tmp_circles[i].circle[0]<<" "<<tmp_circles[i].circle[1]<<" "<<tmp_circles[i].score<<endl;
}
outfile<<endl;
}
//outfile<<circleVV[0].circle[0]<<" "<<circleVV[0].circle[1]<<" "<
2016年05月22日 00点05分 1
level 1
你这个问的.............
2016年05月26日 03点05分 2
level 1
这段代码楼主在哪找的? 链接发一下呗
2019年05月08日 12点05分 3
1