Edge detection on colored background using OpenCV

后端 未结 2 714
执笔经年
执笔经年 2020-12-03 08:50

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

private Mat edgeDetection(Mat src) {
    Mat edges = new Mat();
    Imgproc.cvtColor(src, edge         


        
相关标签:
2条回答
  • 2020-12-03 09:24

    In OpenCV there is function called dilate this will darker the lines. so try the code like below.

    private Mat edgeDetection(Mat src) {
        Mat edges = new Mat();
        Imgproc.cvtColor(src, edges, Imgproc.COLOR_BGR2GRAY);
        Imgproc.dilate(edges, edges, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10, 10)));
        Imgproc.GaussianBlur(edges, edges, new Size(5, 5), 0);
        Imgproc.Canny(edges, edges, 15, 15 * 3);
        return edges;
    }
    
    0 讨论(0)
  • 2020-12-03 09:40

    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)
    
    0 讨论(0)
提交回复
热议问题