banner



Simple Black And White Drawing

I am trying to detect lines, circles and arcs in a simple black and white drawing image file (jpg or bmp format)

I posted a similar question before, in which OpenCV library was suggested. It is a good library, however, it is not accurate enough for my purpose. More specifically, the Canny detection algorithm somehow does not work perfectly for my images.

Hence I am trying to implement the algorithm myself using QImage. I have managed to successfully implement it for straight lines. The code in Qt C++ is as follows. It is a very cluttered code, but I am just giving it for reference.

The algorithm is very simple:
1. I scan the image from top left, row-wise.
2. Whenever I encounter a black pixel, I scan towards its right, left bottom to check whether it is a corner of a line segment.

          for ( int i = 0; i < myImage.height(); i++ ) {          for ( int j = 0; j < myImage.width(); j++ ) {             if ( qGray( myImage.pixel( j, i ) ) == 0 ) {                  myImage.setPixel( j, i, value );                 bool horiLineDrawn = false;                 int xRight = j+1, xLeft = j-1;                 int y = i+1;                 while ( xRight < myImage.width() && qGray( myImage.pixel( xRight, i ) ) == 0 ) {                     myImage.setPixel( xRight, i, value );                     xRight++;                 }                 while ( y < myImage.height() && xLeft >= 0 &&                         qGray( myImage.pixel( xLeft, y ) ) == 0 ) {                     if ( xLeft - 1 >= 0 &&                          qGray( myImage.pixel( xLeft - 1, y ) ) == 0 ) {                         while ( xLeft >= 0 &&                                 qGray( myImage.pixel( xLeft, y ) ) == 0 ) {                             myImage.setPixel( xLeft, y, value );                             xLeft--;                         }                         y++;                     } else if ( y+1 < myImage.height() &&                                 qGray( myImage.pixel( xLeft, y + 1 ) ) == 0 ) {                         while ( y < myImage.height() &&                                 qGray( myImage.pixel( xLeft, y ) ) == 0 ) {                             myImage.setPixel( xLeft, y, value );                             y++;                         }                         xLeft--;                     } else {                         xLeft--;                         y++;                     }                 }                 y--;                 xLeft++;                 if ( y > i && ( y - i > MIN_PIXELS_LINE ||                                 xRight-1 - xLeft > MIN_PIXELS_LINE )                      ) {                     drawFile.Line( fileName2, xRight-1, myImage.height() - i, xLeft,                                    myImage.height() - y, 0 );                     horiLineDrawn = true;                 }                  y = i + 1;                 while ( y < myImage.height() && xRight < myImage.width() &&                         qGray( myImage.pixel( xRight, y ) ) == 0 ) {                       if ( xRight + 1 < myImage.width() &&                          qGray( myImage.pixel( xRight + 1, y ) ) == 0 ) {                         while ( xRight < myImage.width() &&                                 qGray( myImage.pixel( xRight, y ) ) == 0 ) {                             myImage.setPixel( xRight, y, value );                             xRight++;                         }                         y++;                     } else if ( y+1 < myImage.height() &&                                 qGray( myImage.pixel( xRight, y + 1 ) ) == 0 ) {                         while ( y < myImage.height() &&                                 qGray( myImage.pixel( xRight, y ) ) == 0 ) {                             myImage.setPixel( xRight, y, value );                             y++;                         }                         xRight++;                     } else {                         xRight++;                         y++;                     }                 }                 y--;                 xRight--;                 if ( y - i > MIN_PIXELS_LINE || xRight - j > MIN_PIXELS_LINE                      && !horiLineDrawn) {                     drawFile.Line( fileName2, j, myImage.height() - i, xRight,                                    myImage.height() - y, 0 );                     horiLineDrawn = true;                 }                  y = i + 1;                 while ( y < myImage.height() && qGray( myImage.pixel( j, y ) ) == 0 ) {                     myImage.setPixel( j, y, value );                     y++;                 }                 xLeft = j - 1;                 xRight = j + 1;                 if ( xLeft >= 0 && y < myImage.height() &&                      qGray( myImage.pixel( xLeft, y ) ) == 0 ) {                     while ( xLeft >= 0 && y < myImage.height() &&                             qGray( myImage.pixel( xLeft, y ) ) == 0 ) {                         while ( y < myImage.height() &&                                 qGray( myImage.pixel( xLeft, y ) ) == 0 ) {                             myImage.setPixel( xLeft, y, value );                             y++;                         }                         xLeft--;                     }                     xLeft++;                     y--;                     if ( y - i > MIN_PIXELS_LINE || j - xLeft > MIN_PIXELS_LINE )                         drawFile.Line( fileName2, j, myImage.height() - i, xLeft,                                        myImage.height() - y, 0 );                 } else if ( xRight < myImage.width() && y < myImage.height() &&                             qGray( myImage.pixel( xRight, y ) ) == 0 ) {                        while ( xRight < myImage.width() && y < myImage.height() &&                                qGray( myImage.pixel( xRight, y ) ) == 0 ) {                            while ( y < myImage.height() &&                                    qGray( myImage.pixel( xRight, y ) ) == 0 ) {                                myImage.setPixel( xRight, y, value );                                y++;                            }                            xRight++;                        }                        xRight--;                        y--;                        if ( y - i > MIN_PIXELS_LINE || xRight - j > MIN_PIXELS_LINE )                            drawFile.Line( fileName2, j, myImage.height() - i, xRight,                                           myImage.height() - y, 0 );                 } else {                     y--;                     if ( y - i > MIN_PIXELS_LINE )                         drawFile.Line( fileName2, j, myImage.height() - i, j,                                        myImage.height() - y, 0 );                 }               }         }     }                  

This works fine. For example:

Input image:
enter image description here

Output image:
enter image description here

Can anyone suggest how I can implement similar or better algorithm for circles and arcs? Efficiency is not a problem since my image size shall be maximum 1000 by 1000 pixels. However, accuracy is critical.

EDIT: There may be a lot of bugs in my present implementation of straight lines, like I haven't tested it for intersecting lines etc. But I think I shall be able to manage those complications.

Simple Black And White Drawing

Source: https://stackoverflow.com/questions/19912454/detect-lines-circles-and-arcs-in-simple-black-and-white-drawing-image

Posted by: walshculdrought78.blogspot.com

0 Response to "Simple Black And White Drawing"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel