I'm really new to OpenCV. :) I have been working on this for almost an entire day. After hours of sleepless work I would like to know if I can further improve my code.
I have written some code to select only the black markings on the images. These black markings are child contours. Whilst my code is able to select some contours, it isn't accurate. You can see the code draws contours around the shadows along with black markings.
Code 1
At first I tried to use canny edge detection. But I was unable to overlay with the original image correctly.
import cv2
import numpy as np
image = cv2.imread('3.jpg')
image = cv2.resize(image, (500, 500))
image2 = image
cv2.waitKey(0)
# Grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Find Canny edges
edged = cv2.Canny(gray, 30, 200)
cv2.waitKey(0)
contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cv2.imshow('Canny', edged)
cv2.waitKey(0)
# print("Number of Contours found = " + str(len(contours)))
cv2.drawContours(image2, contours, -1, (0, 255, 0), 3)
cv2.imshow('Contours', image2)
cv2.waitKey(0)
cv2.destroyAllWindows()
Code 2
I was able to improve on Code 1 to be far more accurate. You should be able to see that it now only selects half of the thumb, none of the other fingers and it doesn't select the indent on the background.
Additionally changing the background of the image also increases the accuracy of the result.
import cv2
import numpy as np
image = cv2.imread('3.jpg', 0)
image2 = cv2.imread('3.jpg')
image = cv2.resize(image, (500, 500))
image2 = cv2.resize(image2, (500, 500))
cv2.waitKey(0)
ret, thresh_basic = cv2.threshold(image, 100, 255, cv2.THRESH_BINARY)
cv2.imshow("Thresh basic", thresh_basic)
# Taking a matrix of size 5 as the kernel
kernel = np.ones((5, 5), np.uint8)
img_erosion = cv2.erode(thresh_basic, kernel, iterations=1)
#####################
ret, thresh_inv = cv2.threshold(img_erosion, 100, 255, cv2.THRESH_BINARY_INV)
cv2.imshow("INV", thresh_inv)
#####################
# Find Canny edges
edged = cv2.Canny(img_erosion, 30, 200)
cv2.waitKey(0)
contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cv2.imshow('Canny', edged)
cv2.waitKey(0)
# print("Number of Contours found = " + str(len(contours)))
cv2.imshow('Original', image2)
cv2.drawContours(image2, contours, -1, (0, 255, 0), 3)
cv2.imshow('Contours', image2)
cv2.waitKey(0)
cv2.destroyAllWindows()
Can I improve my code further?