对彩色背景进行边缘检测

对彩色背景进行边缘检测

本文介绍了使用 OpenCV 对彩色背景进行边缘检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码检测给定文档的边缘.

private Mat edgeDetection(Mat src) {垫边 = 新垫();Imgproc.cvtColor(src,edges,Imgproc.COLOR_BGR2GRAY);Imgproc.GaussianBlur(edges, edge, new Size(5, 5), 0);Imgproc.Canny(edges, edge, 10, 30);返回边;}

然后我可以通过从中找到最大轮廓来从这个 edges 中找到文档.

我的问题是我可以从以下图片中找到文档:

但不是来自以下图片:

如何改进这种边缘检测?

解决方案

我使用 Python,但主要思想是一样的.

如果直接对img2做cvtColor:bgr->gray,那肯定失败.因为灰色变得难以区分区域:

相关答案:

  1. 这是第二个结果:

    Python 代码(Python 3.5 + OpenCV 3.3):

    #!/usr/bin/python3# 2017.12.20 10:47:28 CST# 2017.12.20 11:29:30 CST导入 cv2将 numpy 导入为 np##(1) 读入 bgr 空间img = cv2.imread("test2.jpg")##(2) 转换为hsv-space,然后拆分通道hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)h,s,v = cv2.split(hsv)##(3) 使用自适应方法(`THRESH_OTSU`)或固定阈值对 S 通道进行阈值处理th, threshed = cv2.threshold(s, 50, 255, cv2.THRESH_BINARY_INV)##(4) 在threshed S上找到所有的外部轮廓cnts = cv2.findContours(threshed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]画布 = img.copy()#cv2.drawContours(canvas, cnts, -1, (0,255,0), 1)##排序并选择最大的轮廓cnts = sorted(cnts, key = cv2.contourArea)cnt = cnts[-1]## 近似轮廓,所以得到角点arclen = cv2.arcLength(cnt, True)approx = cv2.approxPolyDP(cnt, 0.02* arclen, True)cv2.drawContours(canvas, [cnt], -1, (255,0,0), 1, cv2.LINE_AA)cv2.drawContours(canvas, [approx], -1, (0, 0, 255), 1, cv2.LINE_AA)## 好的,你可以看到结果为 tag(6)cv2.imwrite("detected.png", canvas)

    I am using following code to detect edges from given document.

    private Mat edgeDetection(Mat src) {
        Mat edges = new Mat();
        Imgproc.cvtColor(src, edges, Imgproc.COLOR_BGR2GRAY);
        Imgproc.GaussianBlur(edges, edges, new Size(5, 5), 0);
        Imgproc.Canny(edges, edges, 10, 30);
        return edges;
    }
    

    And then I can find the document from this edges by finding largest contour from this.

    My problem is I can find the document from following pic:

    but not from following pic:

    How can I improve this edge detection?

    解决方案

    I use Python, but the main idea is the same.

    If you directly do cvtColor: bgr -> gray for img2, then you must fail. Because the gray becames difficulty to distinguish the regions:


    Related answers:

    1. How to detect colored patches in an image using OpenCV?
    2. Edge detection on colored background using OpenCV
    3. OpenCV C++/Obj-C: Detecting a sheet of paper / Square Detection


    In your image, the paper is white, while the background is colored. So, it's better to detect the paper is Saturation(饱和度) channel in HSV color space. For HSV, refer to https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation.


    Main steps:

    1. Read into BGR
    2. Convert the image from bgr to hsv space
    3. Threshold the S channel
    4. Then find the max external contour(or do Canny, or HoughLines as you like, I choose findContours), approx to get the corners.


    This is the first result:

    This is the second result:

    The Python code(Python 3.5 + OpenCV 3.3):

    #!/usr/bin/python3
    # 2017.12.20 10:47:28 CST
    # 2017.12.20 11:29:30 CST
    
    import cv2
    import numpy as np
    
    ##(1) read into  bgr-space
    img = cv2.imread("test2.jpg")
    
    ##(2) convert to hsv-space, then split the channels
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    h,s,v = cv2.split(hsv)
    
    ##(3) threshold the S channel using adaptive method(`THRESH_OTSU`) or fixed thresh
    th, threshed = cv2.threshold(s, 50, 255, cv2.THRESH_BINARY_INV)
    
    ##(4) find all the external contours on the threshed S
    cnts = cv2.findContours(threshed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
    canvas  = img.copy()
    #cv2.drawContours(canvas, cnts, -1, (0,255,0), 1)
    
    ## sort and choose the largest contour
    cnts = sorted(cnts, key = cv2.contourArea)
    cnt = cnts[-1]
    
    ## approx the contour, so the get the corner points
    arclen = cv2.arcLength(cnt, True)
    approx = cv2.approxPolyDP(cnt, 0.02* arclen, True)
    cv2.drawContours(canvas, [cnt], -1, (255,0,0), 1, cv2.LINE_AA)
    cv2.drawContours(canvas, [approx], -1, (0, 0, 255), 1, cv2.LINE_AA)
    
    ## Ok, you can see the result as tag(6)
    cv2.imwrite("detected.png", canvas)
    

    这篇关于使用 OpenCV 对彩色背景进行边缘检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 17:12