I am trying to develop a “simple” technique to extract edge detection just like Vuforia does (Guide View: https://developer.vuforia.com/library/model-targets/model-target-guide-view), for object recognition.
I am using OpenCV with techniques for edge detection (Canny, Sobel, Laplacian).
The images that i’m considering are reconstructed models. Just for give you 2 examples:
reconstructed-model-1
reconstructed-model-2
If I try to do a Canny edge on this type of images, each color variation can give me information about all the details.
The two images only computed with Canny cannot be a good guide view for object recognition because they have too many contours within them that are not easy to match.
So, when I saw the outputs of the same original images that vuforia calculates as Guide View (the following images), I noticed something.
Vuforia-guide-view-model-1
Vuforia-guide-view-model-2
It seems that vuforia does an edge detection on the depth map of the image, in fact there are no edges related to the color changes.
I have gotten close to their output but they are not yet at that level:
my-guide-view-of-model-1
my-guide-view-of-model-2
The code that i’m running is this:
import cv2
import numpy as np
image = cv2.imread('../GuideView Images/depth_2.png', cv2.IMREAD_COLOR)
# Resize image
image = cv2.resize(image, (0, 0), fx=0.5, fy=0.5)
image_copy = image.copy()
# blur the image
image = cv2.GaussianBlur(image, (3, 3), 0)
# Convert to grayscale
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# # 3x3 Y and X-direction kernel
sobel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
# Filter the image using filter2D, which has inputs: (grayscale image, bit-depth, kernel)
filtered_y = cv2.filter2D(image, -1, sobel_y)
filtered_x = cv2.filter2D(image, -1, sobel_x)
# Sobel edge detection
sobel_x_filtered = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y_filtered = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
sobel_x_filtered = cv2.convertScaleAbs(sobel_x_filtered)
sobel_y_filtered = cv2.convertScaleAbs(sobel_y_filtered)
sobel_filtered = cv2.addWeighted(sobel_x_filtered, 0.5, sobel_y_filtered, 0.5, 0)
cv2.imshow('Sobel filtered', sobel_filtered)
cv2.waitKey(0)
# Dilate the image
dilated_image = cv2.dilate(sobel_filtered, np.ones((3, 3), np.uint8), iterations=1)
cv2.imshow('Dilated image', dilated_image)
cv2.waitKey(0)
# Find the threshold value
threshold_value, thresholded_image = cv2.threshold(dilated_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imshow('Thresholded image', thresholded_image)
cv2.waitKey(0)
# Canny edge detection - Guide View
canny = cv2.Canny(dilated_image, 0.47 * threshold_value, 0.7 * threshold_value)
cv2.imshow('Guide View', canny)
cv2.waitKey(0)
# Save the image
cv2.imwrite('GuideView_0001_2.jpg', canny)
# Find the contours
contours, _ = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Draw the contours
cv2.drawContours(image_copy, contours, -1, (0, 255, 0), 1)
cv2.imshow('Contours', image_copy)
cv2.waitKey(0)
What do you think?
Also I would like to figure out how to maybe merge those contours that are close together, I haven’t found methods like non maximum suppression for this approach.
Sabeeno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.