Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Difficult edge detection using Canny

Hello, For a school project I am trying to perform Canny edge detection on images to be able to acquire the width of the object and thus figure out the distance camera/object. These images are obtained through a video stream and the object I am working on is a "LEGO Super Battle Droid Set 8012". First of all, I use Haar cascade to detect it in the picture, then I want to use a Sobel Filter + Canny to obtain this width. To detect it better only the upper part of the object is to be detected. The problem I encounter is that the program doesn't seem to find the edges of it.This may be due to the previous Haar cascade "crop" of the image, but I'm not sure... The images loaded in the program are from a video stream, and the program is done as if the Haar cacade process was done (images are cropped in the program to imitate it).

# -*- coding: utf-8 -*-

import cv2
import numpy as np

#1M2.jpg [280:650, 1000:1250]
#1M0.jpg: [220:550, 900:1200]

def find_marker(sigma = 0.33):
    DIST_IMG = cv2.imread("0M8.jpg")
    sobel_img = DIST_IMG[130:550, 900:1250]#image "like" obtained trough haarcascade process
    sobel_img = cv2.cvtColor(sobel_img, cv2.COLOR_BGR2GRAY)
    sobel_img = cv2.GaussianBlur(sobel_img, (15,15), 0)#blur image to reduce noise
    upper = int(min(255, (1.0 + sigma) * np.median(sobel_img)))
    sobelx = cv2.Sobel(sobel_img,cv2.CV_64F,1,0,ksize=3)
    sobely = cv2.Sobel(sobel_img,cv2.CV_64F,0,1,ksize=3)
    np.abs(sobelx, sobelx)
    np.abs(sobely, sobely)
    sobelx = np.uint8(sobelx)
    sobely = np.uint8(sobely)
    cv2.add(sobelx, sobely, sobel_img)
    edged = cv2.Canny(sobel_img, np.int0(upper/2), upper)
    (_, cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    c = max(cnts, key = cv2.contourArea)#find largest element in the image
    cv2.imshow('image', edged)
    cv2.waitKey(0)
    return cv2.minAreaRect(c)

image = cv2.imread("0M8.jpg")
image = image[130:550, 900:1250]
marker = find_marker()
pts = np.int0(cv2.boxPoints(marker))
x, y, w, h = cv2.boundingRect(pts)
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow("image", image)
cv2.waitKey(0)

Image at 0.8 meters distance: 0M8.jpg

Image at 1 meter distance: 1M0.jpg

Image at 1.2 meters distance: 1M2.jpg

Best regards, Pitt

Difficult edge detection using Canny

Hello, For a school project I am trying to perform Canny edge detection on images to be able to acquire the width of the object and thus figure out the distance camera/object. These images are obtained through a video stream and the object I am working on is a "LEGO Super Battle Droid Set 8012". First of all, I use Haar cascade to detect it in the picture, then I want to use a Sobel Filter + Canny to obtain this width. To detect it better only the upper part of the object is to be detected. The problem I encounter is that the program doesn't seem to find the edges of it.This may be due to the previous Haar cascade "crop" of the image, but I'm not sure... The images loaded in the program are from a video stream, and the program is done as if the Haar cacade process was done (images are cropped in the program to imitate it).

# -*- coding: utf-8 -*-

import cv2
import numpy as np

#1M2.jpg [280:650, 1000:1250]
#1M0.jpg: [220:550, 900:1200]

def find_marker(sigma = 0.33):
    DIST_IMG = cv2.imread("0M8.jpg")
    sobel_img = DIST_IMG[130:550, 900:1250]#image "like" obtained trough haarcascade process
    sobel_img = cv2.cvtColor(sobel_img, cv2.COLOR_BGR2GRAY)
    sobel_img = cv2.GaussianBlur(sobel_img, (15,15), 0)#blur image to reduce noise
    upper = int(min(255, (1.0 + sigma) * np.median(sobel_img)))
    sobelx = cv2.Sobel(sobel_img,cv2.CV_64F,1,0,ksize=3)
    sobely = cv2.Sobel(sobel_img,cv2.CV_64F,0,1,ksize=3)
    np.abs(sobelx, sobelx)
    np.abs(sobely, sobely)
    sobelx = np.uint8(sobelx)
    sobely = np.uint8(sobely)
    cv2.add(sobelx, sobely, sobel_img)
    edged = cv2.Canny(sobel_img, np.int0(upper/2), upper)
    (_, cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    c = max(cnts, key = cv2.contourArea)#find largest element in the image
    cv2.imshow('image', edged)
    cv2.waitKey(0)
    return cv2.minAreaRect(c)

image = cv2.imread("0M8.jpg")
image = image[130:550, 900:1250]
marker = find_marker()
pts = np.int0(cv2.boxPoints(marker))
x, y, w, h = cv2.boundingRect(pts)
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow("image", image)
cv2.waitKey(0)

Image at 0.8 meters distance: 0M8.jpg

Image at 1 meter distance: 1M0.jpg

Image at 1.2 meters distance: 1M2.jpg

Best regards, Pitt