5
\$\begingroup\$

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()

The original image and contours

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()

enter image description here enter image description here

Can I improve my code further?

\$\endgroup\$
6
  • \$\begingroup\$ That's not an easy picture to work with. Have you tried making a hogh-contrast version of it to assist in the contour detection? Check for contours in both, see the differences. \$\endgroup\$
    – Mast
    Jun 19, 2020 at 4:56
  • \$\begingroup\$ @Mast, I've decided to change the background color. \$\endgroup\$ Jun 19, 2020 at 5:31
  • \$\begingroup\$ Keep in mind that general review is on-topic here, but issues of accuracy improvement will not be. \$\endgroup\$
    – Reinderien
    Jun 19, 2020 at 15:56
  • \$\begingroup\$ @Reinderien Whilst you would normally be correct. We have long classed ML accuracy to be similar to performance, TLE or memory optimization. \$\endgroup\$
    – Peilonrayz
    Jun 19, 2020 at 19:49
  • 1
    \$\begingroup\$ @Reinderien No problem. This section of our rules can be rather confusing. :) \$\endgroup\$
    – Peilonrayz
    Jun 19, 2020 at 20:44

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.