45 cvReleaseImage(&
gray);
50 bool Labeling::CheckBorder(CvSeq* contour,
int width,
int height)
53 for(
int i = 0; i < contour->total; ++i)
55 CvPoint* pt = (CvPoint*)cvGetSeqElem(contour, i);
56 if((pt->x <= 1) || (pt->x >= width-2) || (pt->y <= 1) || (pt->y >= height-2)) ret =
false;
61 LabelingCvSeq::LabelingCvSeq() : _n_blobs(0), _min_edge(20), _min_area(25)
64 storage = cvCreateMemStorage(0);
80 if (
gray && ((
gray->width != image->width) || (
gray->height != image->height))) {
82 if (
bw) cvReleaseImage(&
bw);
bw=NULL;
85 gray = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1);
86 gray->origin = image->origin;
87 bw = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1);
88 bw->origin = image->origin;
92 if(image->nChannels == 4)
93 cvCvtColor(image,
gray, CV_RGBA2GRAY);
94 else if(image->nChannels == 3)
95 cvCvtColor(image,
gray, CV_RGB2GRAY);
96 else if(image->nChannels == 1)
99 cerr<<
"Unsupported image format"<<endl;
106 CvSeq* squares = cvCreateSeq(0,
sizeof(CvSeq),
sizeof(CvSeq),
storage);
107 CvSeq* square_contours = cvCreateSeq(0,
sizeof(CvSeq),
sizeof(CvSeq),
storage);
109 cvFindContours(
bw,
storage, &contours,
sizeof(CvContour),
110 CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
116 contours = contours->h_next;
120 CvSeq* result = cvApproxPoly(contours,
sizeof(CvContour),
storage,
121 CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.035, 0 );
123 if( result->total == 4 &&
CheckBorder(result, image->width, image->height) &&
124 fabs(cvContourArea(result,CV_WHOLE_SEQ)) >
_min_area &&
125 cvCheckContourConvexity(result) )
127 cvSeqPush(squares, result);
128 cvSeqPush(square_contours, contours);
130 contours = contours->h_next;
139 vector<Line> fitted_lines(4);
141 CvSeq* sq = (CvSeq*)cvGetSeqElem(squares, i);
142 CvSeq* square_contour = (CvSeq*)cvGetSeqElem(square_contours, i);
144 for(
int j = 0; j < 4; ++j)
146 CvPoint* pt0 = (CvPoint*)cvGetSeqElem(sq, j);
147 CvPoint* pt1 = (CvPoint*)cvGetSeqElem(sq, (j+1)%4);
149 for (
int k = 0; k<square_contour->total; k++) {
150 CvPoint* pt2 = (CvPoint*)cvGetSeqElem(square_contour, k);
151 if ((pt0->x == pt2->x) && (pt0->y == pt2->y)) k0=k;
152 if ((pt1->x == pt2->x) && (pt1->y == pt2->y)) k1=k;
155 if (k1 >= k0) len = k1-k0-1;
156 else len = square_contour->total-k0+k1-1;
157 if (len == 0) len = 1;
159 CvMat* line_data = cvCreateMat(1, len, CV_32FC2);
160 for (
int l=0; l<len; l++) {
161 int ll = (k0+l+1)%square_contour->total;
162 CvPoint* p = (CvPoint*)cvGetSeqElem(square_contour, ll);
171 CV_MAT_ELEM(*line_data, CvPoint2D32f, 0, l) = pp;
175 float params[4] = {0};
188 cvFitLine(line_data, CV_DIST_L2, 0, 0.01, 0.01, params);
193 if(visualize)
DrawLine(image, line);
194 fitted_lines[j] = line;
196 cvReleaseMat(&line_data);
200 for(
size_t j = 0; j < 4; ++j)
226 for(
size_t j = 0; j < 4; ++j) {
228 if (j == 0) cvCircle(image, cvPoint(
int(intc.x),
int(intc.y)), 5, CV_RGB(255, 255, 255));
229 if (j == 1) cvCircle(image, cvPoint(
int(intc.x),
int(intc.y)), 5, CV_RGB(255, 0, 0));
230 if (j == 2) cvCircle(image, cvPoint(
int(intc.x),
int(intc.y)), 5, CV_RGB(0, 255, 0));
231 if (j == 3) cvCircle(image, cvPoint(
int(intc.x),
int(intc.y)), 5, CV_RGB(0, 0, 255));
241 assert(image->origin == 0);
242 if (
gray && ((
gray->width != image->width) || (
gray->height != image->height))) {
244 if (
bw) cvReleaseImage(&
bw);
bw=NULL;
247 gray = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1);
248 gray->origin = image->origin;
249 bw = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1);
250 bw->origin = image->origin;
254 if(image->nChannels == 4)
255 cvCvtColor(image,
gray, CV_RGBA2GRAY);
256 else if(image->nChannels == 3)
257 cvCvtColor(image,
gray, CV_RGB2GRAY);
258 else if(image->nChannels == 1)
261 cerr<<
"Unsupported image format"<<endl;
267 CvSeq* edges = cvCreateSeq(0,
sizeof(CvSeq),
sizeof(CvSeq),
storage);
268 CvSeq* squares = cvCreateSeq(0,
sizeof(CvSeq),
sizeof(CvSeq),
storage);
270 cvFindContours(
bw,
storage, &contours,
sizeof(CvContour),
271 CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
278 if(contours->total < min_size)
280 contours = contours->h_next;
286 CvSeq* result = cvApproxPoly(contours,
sizeof(CvContour),
storage,
287 CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 );
289 if(cvCheckContourConvexity(result))
291 cvSeqPush(squares, result);
295 cvSeqPush(squares, contours);
297 contours = contours->h_next;
306 return (x)>=0?(int)((x)+0.5):(int)((x)-0.5);
311 return (c2>c1?c2-c1:c1-c2);
335 IplImage *tmp = cvCreateImage(cvSize(gray->width, gray->height), IPL_DEPTH_8U, 3);
336 IplImage *tmp2 = cvCreateImage(cvSize(gray->width*5, gray->height*5), IPL_DEPTH_8U, 3);
337 cvCvtColor(gray, tmp, CV_GRAY2RGB);
338 cvResize(tmp, tmp2, CV_INTER_NN);
342 CvPoint2D32f *p1 = (CvPoint2D32f*)CV_MAT_ELEM_PTR_FAST(*line_data, 0, 0,
sizeof(CvPoint2D32f));
343 CvPoint2D32f *p2 = (CvPoint2D32f*)CV_MAT_ELEM_PTR_FAST(*line_data, 0, line_data->cols-1,
sizeof(CvPoint2D32f));
344 double dx = +(p2->y - p1->y);
345 double dy = -(p2->x - p1->x);
346 if ((dx == 0) && (dy == 0))
return;
347 else if (dx == 0) { dy /= dy; }
348 else if (dy == 0) { dx /= dx; }
349 else if (abs(dx) > abs(dy)) { dy /= dx; dx /= dx; }
350 else { dx /= dy; dy /= dy; }
353 const int win_size=5;
354 const int win_mid=win_size/2;
355 const int diff_win_size=win_size-1;
356 double xx[win_size], yy[win_size];
357 double dxx[diff_win_size], dyy[diff_win_size];
358 xx[win_mid] = 0; yy[win_mid] = 0;
359 for (
int i=1; i<=win_size/2; i++) {
360 xx[win_mid + i] =
round(i*dx);
361 xx[win_mid - i] = -xx[win_mid + i];
362 yy[win_mid + i] =
round(i*dy);
363 yy[win_mid - i] = -yy[win_mid + i];
365 for (
int i=0; i<diff_win_size; i++) {
366 dxx[i] = (xx[i]+xx[i+1])/2;
367 dyy[i] = (yy[i]+yy[i+1])/2;
371 for (
int l=0; l<line_data->cols; l++) {
372 CvPoint2D32f *p = (CvPoint2D32f*)CV_MAT_ELEM_PTR_FAST(*line_data, 0, l,
sizeof(CvPoint2D32f));
374 double dx=0, dy=0, ww=0;
375 for (
int i=0; i<diff_win_size; i++) {
376 unsigned char c1 = (
unsigned char)gray->imageData[
int((p->y+yy[i])*gray->widthStep+(p->x+xx[i]))];
377 unsigned char c2 = (
unsigned char)gray->imageData[
int((p->y+yy[i+1])*gray->widthStep+(p->x+xx[i+1]))];
379 cvCircle(tmp2, cvPoint((p->x+xx[i])*5+2,(p->y+yy[i])*5+2), 0, CV_RGB(0,0,255));
380 cvCircle(tmp2, cvPoint((p->x+xx[i+1])*5+2,(p->y+yy[i+1])*5+2), 0, CV_RGB(0,0,255));
391 cvLine(tmp2, cvPoint(p->x*5+2,p->y*5+2), cvPoint((p->x+dx)*5+2, (p->y+dy)*5+2), CV_RGB(0,255,0));
392 p->x += float(dx); p->y += float(dy);
393 cvCircle(tmp2, cvPoint(p->x*5+2,p->y*5+2), 0, CV_RGB(255,0,0));
395 p->x += float(dx); p->y += float(dy);
400 cvNamedWindow(
"tmp");
401 cvShowImage(
"tmp",tmp2);
403 cvReleaseImage(&tmp);
404 cvReleaseImage(&tmp2);
This file implements connected component labeling.
This file implements a collection of functions that are used to visualize lines, contours and corners...
bool CheckBorder(CvSeq *contour, int width, int height)
IplImage * bw
Pointer to binary image that is then labeled.
void FitLineGray(CvMat *line_data, float params[4], IplImage *gray)
std::vector< std::vector< PointDouble > > blob_corners
Vector of 4-length vectors where the corners of detected blobs are stored.
Struct representing a line. The line is parametrized by its center and direction vector.
bool detect_pose_grayscale
void SetOptions(bool _detect_pose_grayscale=false)
CvSeq * LabelImage(IplImage *image, int min_size, bool approx=false)
void ALVAR_EXPORT DrawLine(IplImage *image, const Line line, CvScalar color=CV_RGB(0, 255, 0))
Draws a line.
IplImage * gray
Pointer to grayscale image that is thresholded for labeling.
TFSIMD_FORCE_INLINE const tfScalar & w() const
void LabelSquares(IplImage *image, bool visualize=false)
Labels image and filters blobs to obtain square-shaped objects from the scene.
void Distort(CvPoint2D32f &point)
Applys the lens distortion for one point on an image plane.
PointDouble ALVAR_EXPORT Intersection(const Line &l1, const Line &l2)
Calculates an intersection point of two lines.
ALVAR_EXPORT Point< CvPoint2D64f > PointDouble
The default double point type.
void Undistort(std::vector< PointDouble > &points)
Unapplys the lens distortion for points on image plane.