How to determine the width of the lines?

I need to determine the width of these lines:

enter image description here

These lines are parallel and have some noise on them.

I am currently doing:

1. Direct the center using thinning (ZhangSuen)

ZhanSuenThinning(binImage, thin);

2. Evaluate distance conversion

cv::distanceTransform(binImage, distImg, CV_DIST_L2, CV_DIST_MASK_5);

3. Compare the half distance around the center

double halfWidth = 0.0;
int count = 0;
for(int a = 0; a < thinImg.cols; a++)
    for(int b = 0; b < thinImg.rows; b++)
        if(thinImg.ptr<uchar>(b, a)[0] > 0)
        {
            halfWidth += distImg.ptr<float>(b, a)[0];
            count ++;
        }

4. Finally, get the actual width

width = halfWidth / count * 2;

The result is not entirely good, where it is the wrong size of 1-2 pixels. On a large image, the result is even worse. Any suggestion?

+4
source share
5 answers

You can adapt the barcode reader algorithm , which is a faster way to do this.

image

. X , Y - ( X Y, ).

X * Y / 2 = area
X²+Y² = hypotenuse²
hypotenuse * width / 2 = area

: = 2 * /

EDIT: PCA.

+7

RotatedRect , OpenCV, . "" , , . , , .

Contour-->RotatedRect 
              | 
              '-->  Size2f size
                            |
                            |-->width
                            '-->height

RotatedRect minRect = minAreaRect( Mat(contours[i]) );
Size2f contourSize=minRect.size  //  width and height of the rectangle

enter image description here

++

Mat src=imread("line.png",1);
Mat thr,gray;
blur(src,src,Size(3,3));
cvtColor(src,gray,CV_BGR2GRAY);
Canny(gray,thr,50, 190, 3, false );
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours( thr.clone(),contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
vector<RotatedRect> minRect( contours.size() );

for( int i = 0; i < contours.size(); i++ )
  minRect[i] = minAreaRect( Mat(contours[i]) );

for( int i = 0; i< contours.size(); i++ )
 {
    cout<<"  Size ="<<minRect[i].size<<endl; //The width may interchange according to contour alignment
    Size2f s=minRect[i].size;
    // rotated rectangle
    Point2f rect_points[4]; minRect[i].points( rect_points );
    for( int j = 0; j < 4; j++ )
      line( src, rect_points[j], rect_points[(j+1)%4], Scalar(0,0,255), 1, 8 );
}

imshow("src",src);
imshow("Canny",thr);
+4
  • Hough
  • , , . , .
  • /, . , 10- 90- . , : W, S.

, "" , .

+2

:

  • .

  • . (, CVHoughLinesP )

  • , .

, , . .

, , :

  • , .
  • ,
    ( , , . , ).
  • ( , x% ).
  • (rectangle_width * number_of_lines_in_rectangle)
+1

, , /, , , ; , . , .

, , , , - , . , .

Another situation with the real word is when you have gray pixels close to the line border. You can use a threshold to drop them or count them with some weight <1. ​​This compensates for blurring. By the way, rotating the image can increase blur, as it is usually done with interpolation and smoothing.

0
source

Source: https://habr.com/ru/post/1529313/


All Articles