histrionics
histrionics

Reputation: 45

Improving Canny Edge Detection

When I run the cv.Canny edge detector on drawings, it detects hundreds of little edges densely packed in the shaded areas. How can I get it to stop doing that, while still detecting lighter features like eyes and nose? I tried blurring too.

Here's an example, compared with an online photo tool.

Original image.
Output of online tool.
My python program

Here's my code:

def outline(image, sigma = 5):
    image = cv.GaussianBlur(image, (11, 11), sigma)
    ratio = 2
    lower = .37 * 255
    upper = lower * ratio
    outlined = cv.Canny(image, lower, upper)

    return outlined

How can I improve it?

Upvotes: 1

Views: 11624

Answers (2)

histrionics
histrionics

Reputation: 45

I was successfully able to make cv.Canny give satisfactory results by changing the kernel dimension from (11, 11) to (0, 0), allowing the kernel to be dynamically determined by sigma. By doing this and tuning sigma, I got pretty good results. Also, cv.imshow distorts images, so when I was using it to test, the results looked significantly worse than they actually were.

Upvotes: 1

fmw42
fmw42

Reputation: 53081

Here is one way to do that in Python/OpenCV.

Morphologic edge out is the absolute difference between a mask and the dilated mask

  • Read the input
  • Convert to gray
  • Threshold (as mask)
  • Dilate the thresholded image
  • Compute the absolute difference
  • Invert its polarity as the edge image
  • Save the result

Input:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread("cartoon.jpg")

# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold
thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)[1]

# morphology edgeout = dilated_mask - mask
# morphology dilate
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilate = cv2.morphologyEx(thresh, cv2.MORPH_DILATE, kernel)

# get absolute difference between dilate and thresh
diff = cv2.absdiff(dilate, thresh)

# invert
edges = 255 - diff

# write result to disk
cv2.imwrite("cartoon_thresh.jpg", thresh)
cv2.imwrite("cartoon_dilate.jpg", dilate)
cv2.imwrite("cartoon_diff.jpg", diff)
cv2.imwrite("cartoon_edges.jpg", edges)

# display it
cv2.imshow("thresh", thresh)
cv2.imshow("dilate", dilate)
cv2.imshow("diff", diff)
cv2.imshow("edges", edges)
cv2.waitKey(0)


Thresholded image:

enter image description here

Dilated threshold image:

enter image description here

Difference image:

enter image description here

Edge image:

enter image description here

Upvotes: 4

Related Questions