锐化边缘 [英] Sharpen the edges

查看:408
本文介绍了锐化边缘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试检测最大/最大的矩形形状并将边界框绘制到检测到的区域。
我尝试过不同的方法来检测轮廓检测的完美边缘(没有孔的边缘)。我搜索了stackoverflow并提出了解决方案



我同意这不是你所期待的,但可能是一个很好的起点。希望这会有所帮助:)


I am trying to detect the biggest/larger rectangular shape and draw bounding box to the detected area. I have tried different way to detect perfect edge ( Edges with no holes) for contour detection. I searched on stackoverflow and the solution proposed OpenCV sharpen the edges (edges with no holes) and Segmentation Edges did not work with my sample image.

I would like to detect biggest/larger rectangular shape on the following two images Original Image 1 and Original Image 2

Below is the code that i use to preprocess the image before calling findcontour.

public  Mat processGrayScaleImage(Mat grayImage){
    Mat value = new Mat();
    Mat sobx = new Mat();
    Mat soby = new Mat();
    Mat grad_abs_val_approx = new Mat();

    Imgproc.GaussianBlur(grayImage, value, new Size(9, 9), 2, 2);
    Mat imf = new Mat();
    value.convertTo(imf, CV_32FC1, 0.5f, 0.5f);

    Imgproc.Sobel(imf, sobx, -1, 1, 0);
    Imgproc.Sobel(imf, soby, -1, 0, 1);

    sobx = sobx.mul(sobx);
    soby = soby.mul(soby);

    Mat sumxy = new Mat();
    //Core.add(sobx,soby, sumxy);
    Core.addWeighted(sobx, 0.5, soby, 0.5, 0, sumxy);
    Core.pow(sumxy, 0.5, grad_abs_val_approx);

    sobx.release();
    soby.release();
    sumxy.release();;


    Mat filtered = new Mat();
    Imgproc.GaussianBlur(grad_abs_val_approx, filtered, new Size(9, 9), 2, 2);
    grad_abs_val_approx.release();

    final MatOfDouble mean = new MatOfDouble();
    final MatOfDouble stdev = new MatOfDouble();
    Core.meanStdDev(filtered, mean, stdev);

    Mat thresholded = new Mat();
    Imgproc.threshold(filtered, thresholded, mean.toArray()[0], 1.0, Imgproc.THRESH_TOZERO);


    Mat converted = new Mat();
    thresholded.convertTo(converted, CV_8UC1);

    thresholded.release();
    filtered.release();

    return converted;

}

I have also tried the saturation Channel in HSV color space in place of gray image but it does not work.

Does anybody have an idea why it does not works with the code posted above ?

How can I process image in order to sharpen the edges for contour detection ?

Any relevant information(either in Java or C++ or Python ) is welcomed.

//UPDATE : 05/04/2017

I have tested difference of gaussian on the first original image. The result is not useful for contour detection. The resulting image xhttps://i.stack.imgur.com/ONw9F.jpg The code i used :

public static Mat dog(Mat grayImage){
    Mat blur1 = new Mat();
    Mat blur2 = new Mat();
    Mat dog = new Mat();
    int radius1 = 15;
    int radius2 = radius1 + 6;

    Imgproc.GaussianBlur(grayImage, blur1, new Size(radius1, radius1), 5);
    Imgproc.GaussianBlur(grayImage, blur2, new Size(radius2, radius2), 5);
    Core.absdiff(blur1, blur2, dog);


    Core.multiply(dog, new Scalar(100), dog);
    Imgproc.threshold(dog, dog, 55, 255, Imgproc.THRESH_BINARY_INV);

    return dog;

}

I have also tried to apply CLAHE before difference of gaussian and here is the result [Image result of difference of gaussian and clahe] xhttps://i.stack.imgur.com/DDbqg.jpg

Update #2

I have tried the houghline as suggested below but it does not work. here is my code applied to grayscale image

 public static void houghLines(Mat greyImg, Context ctx){
    Mat lines = new Mat();
    Mat binary = new Mat();
    Mat original = greyImg.clone();
    int threshold = 35;
    int minLineSize = 20;
    int lineGap = 30;

    Imgproc.Canny(greyImg, greyImg, 20, 30, 3, false);

    Imgproc.HoughLinesP(greyImg, lines, 1, Math.PI/70, threshold, minLineSize, lineGap);
    for (int x = 0; x < lines.rows(); x++)
    {
        double[] vec = lines.get(x, 0);
        double x1 = vec[0],
                y1 = vec[1],
                x2 = vec[2],
                y2 = vec[3];
        Point start = new Point(x1, y1);
        Point end = new Point(x2, y2);
        double dx = x1 - x2;
        double dy = y1 - y2;

        double dist = Math.sqrt (dx*dx + dy*dy);

        if(dist>300.d)  
            Imgproc.line(original, start, end, new Scalar(0,255, 0, 255),5);

    }
}

The result image after i applied canny xhttps://i.stack.imgur.com/VtGNl.jpg and the final result xhttps://i.stack.imgur.com/KIUan.jpg

Update #3 : 06/04/2017

I tried Houghlines and not HoughlinesP. It does not work. Below is the code

 public static void houghLines(Mat Original, Context ctx){
    Mat lines = new Mat();
    Mat binary = new Mat();
    Mat greyImg = new Mat();
    Mat im = Original.clone();

    Imgproc.cvtColor(im, greyImg, Imgproc.COLOR_RGB2GRAY);

    Imgproc.Canny(greyImg, binary, 20, 30, 3, true);

    Imgproc.HoughLines(binary, lines, 1, Math.PI/70, 35);

    for (int i = 0; i < lines.cols(); i++){
        double data[] = lines.get(0, i);
        double rho = data[0];
        double theta = data[1];
        double cosTheta = Math.cos(theta);
        double sinTheta = Math.sin(theta);
        double x0 = cosTheta * rho;
        double y0 = sinTheta * rho;
        Point pt1 = new Point(x0 + 10000 * (-sinTheta), y0 + 10000 * cosTheta);
        Point pt2 = new Point(x0 - 10000 * (-sinTheta), y0 - 10000 * cosTheta);
        Imgproc.line(im, pt1, pt2, new Scalar(0, 0, 200), 3);
    }

}

The resulting canny image for the code above : _https://i.stack.imgur.com/6k8sF.jpg The resulting image with lines _https://i.stack.imgur.com/3e9CB.jpg

At this time of writing, i have not found a working solution. Does anybody have an idea for a working solution ?

解决方案

I tried a quick check on the image you shared. And I got this result after I tweaked parameters of canny and hough lines a little. Not sure what kind of generalisation you need, but give it a try.

Here is my code:

import cv2 as cv2
import numpy as np

# fn = '2PeyG.jpg'
fn = 'qEFMj.jpg'
r_scale = 0.1
# OpenCV reads image with BGR format
img = cv2.imread(fn)
img = cv2.resize(img, (0, 0), fx=r_scale, fy=r_scale)
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(img, 20, 30, apertureSize=3)


lines = cv2.HoughLines(edges, 1, np.pi/70, 35)

for rho, theta in lines[0]:
    if (np.pi/70 <= theta <= np.pi/7) or (2.056 < theta < 4.970) or (1.570 <= theta <= 1.600):

        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a*rho
        y0 = b*rho
        x1 = int(x0 + 1000*(-b))
        y1 = int(y0 + 1000*(a))

        x2 = int(x0 - 1000*(-b))
        y2 = int(y0 - 1000*(a))

        cv2.line(img,(x1,y1),(x2,y2),(0,0,255),1)


cv2.imshow('edges', edges)
cv2.imshow('overlay', img)

# cv2.imwrite('lines_overlay.png', img)
cv2.waitKey(3000)

The result I got was

I agree this is not what you are looking exactly, but probably a good starting point. Hope this helps :)

这篇关于锐化边缘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆