How to remove the unnecessary line segments from the image?

asked 2015-04-23 04:10:25 -0500

cv_new gravatar image

updated 2015-04-23 23:06:44 -0500

I want to turn my original image "Original Image" into the target image "Target Image". And I manage to use OpenCV's Hough Transform to remove the line segments. However, the results come out not as expected (Referring to "Resulting image"). From the resulting image, the line segments are not extracted as I want.

I have looked into this web page, but since some line segments are not in a horizontal direction. I find it is unsuitable to apply in my work.

From the resulting image, the left vertical line is divided into two parts. But what I hope is to extract a whole vertical line segments seen in the original image. For the extracted upper line and the skew line segments, they are not shaped as the actual lines in the original image. I wonder how to perfectly remove those lines segments? What is the efficient way to get my work done? Thanks.

My code:

    Mat tempImg,binaryImg, edges;

Mat im = imread("C:\\apple.bmp");

cvtColor(im, tempImg, CV_BGR2GRAY); 

adaptiveThreshold( tempImg, binaryImg, 200, CV_ADAPTIVE_THRESH_MEAN_C , CV_THRESH_BINARY , 7, 15 );

imwrite("binaryImg.png",binaryImg);

Canny(binaryImg, edges, 40, 120, 3);    

threshold(edges, edges, 128, 255.0, THRESH_BINARY);

vector<Vec4i> lines;
HoughLinesP(edges, lines, 1, CV_PI/180, 50, 20, 10 );
cv::Mat outImg = cv::Mat::zeros(binaryImg.rows, binaryImg.cols, CV_8UC3);

for( size_t i = 0; i < lines.size(); i++ )
{
    Vec4i l = lines[i];
    line( outImg, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255,255,255), 3, CV_AA);
}

imwrite("outImg.bmp",outImg);

Original Image

Original Image

Target Image

Target Image

Resulting image

Resulting image


I have tried to use OpenCV's inpainting, but I find the inpainting is not perfect enough. Though I have the mask, the resulting image has still a large area of black region on the left hand side. This area is not removed under OpenCV's impainting. I don't really know why the mask doesn't take into effect. I wonder how to make the impainting better.

My code:

Mat tempImg,binaryImg, edges,eroded;
    Mat im = imread("C:\\apple.bmp");

    cvtColor(im, tempImg, CV_BGR2GRAY); 

    adaptiveThreshold( tempImg, binaryImg, 128, CV_ADAPTIVE_THRESH_MEAN_C , CV_THRESH_BINARY , 7, 15 );


    imwrite("binaryImg.png",binaryImg);

    Canny(binaryImg, edges, 40, 120, 3);    

    threshold(edges, edges, 128, 255.0, THRESH_BINARY);

    vector<Vec4i> lines;
    HoughLinesP(edges, lines, 1, CV_PI/180, 50, 20, 10 );
    cv::Mat outImg = cv::Mat::zeros(binaryImg.rows, binaryImg.cols, CV_8UC3);

    for( size_t i = 0; i < lines.size(); i++ )
    {
        Vec4i l = lines[i];
        line( outImg, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255,255,255), 3, CV_AA);
    }

    Mat mask,newImg;
    Mat element(10,10,CV_8U,Scalar(1));  
    dilate(outImg,eroded,element); 


    cv::cvtColor(eroded, mask, CV_BGR2GRAY);    
    std::vector<std::vector<cv::Point> > contours;
    cv::findContours(tempImg.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

    for (int i = 0; i < contours.size(); i++)
    {
        cv::Rect r = cv::boundingRect(contours[i]);

        if (std::abs(1 - (tempImg.cols/r.width)) > 0.2)
            cv::drawContours(mask, contours, i, CV_RGB(0,0,0), CV_FILLED);
    }

    imwrite("mask.bmp",mask);
    inpaint(im, mask, newImg, 1, cv::INPAINT_TELEA ...
(more)
edit retag flag offensive close merge delete

Comments

Have you tried Hough to detect lines and then eliminate those lines? I have thought of something like create the mask of the lines and apply inpainting. This should do your expected work.

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-04-23 06:09:59 -0500 )edit

Thank you very much. I will follow your idea to do my work. :) By the way, the resulting image is formed by the Hough transform applied to the original image.

cv_new gravatar imagecv_new ( 2015-04-23 21:31:09 -0500 )edit

I have done the impainting., but the impainting is not well enough as mentioned in my updated question. @thdrksdfthmn

cv_new gravatar imagecv_new ( 2015-04-23 23:07:50 -0500 )edit

Maybe using closing instead of dilate? Inpainting is not very good on thick lines that contain edges...

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-04-24 02:22:32 -0500 )edit

Thanks. I now plan to use counting to remove them.

cv_new gravatar imagecv_new ( 2015-05-03 23:00:18 -0500 )edit