I want to count leathers on a stacked leather image, any image processing help is appreciated.
After below some python
codes, I realized my code is not a robust method, it can totally change depending on function parameters values and input images. I need a robust method to handle this problem. Thank you for your efforts.
import cv2
path= r'image.bmp'
im = cv2.imread(path)
im = cv2.resize(im, (640,480), interpolation = cv2.INTER_AREA)
cv2.imwrite('savedImage2.jpg', im)
im = cv2.GaussianBlur(im, (7,7), sigmaX=31)
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
im = cv2.inRange(im, 50, 90)
cv2.imshow('image', im)
cv2.waitKey(0)
cv2.destroyAllWindows()
(leather count=8 in image, truth value=8
(leather count=8 in image, truth value=8)
This is a simple idea and certainly not suitable for all test_cases. Note that the more time you spend, the more images you review and the more you read the image processing tools; You will achieve better results and find better solutions. So this is not something that you can get the best possible answer in a few minutes. The next issue is environmental conditions. The less you change the environment, the less error you will have.
import cv2
import sys
import math
import numpy as np
# Load image
org = cv2.imread(sys.path[0]+'/1.jpg')
im = org.copy()
H, W = im.shape[:2]
# Make a clean binary image
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
im = cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
im = cv2.medianBlur(im, 5)
# Slice top of the image
org = org[0:20, 0:W]
im = im[0:20, 0:W]
H, W = im.shape[:2]
# Clean lines like a barcode
im = cv2.GaussianBlur(im, (1,31), 31)
im=cv2.threshold(im,127,255,cv2.THRESH_BINARY)[1]
cv2.rectangle(im, (0, 0), (W, H), 255, 3)
# Find contours
cnts, _ = cv2.findContours(im, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
for cnt in cnts:
x, y, w, h = cv2.boundingRect(cnt)
if w < W:
cv2.rectangle(im, (x, y), (x+w, y+h), (0, 255, 0), 1)
# Count lines
lines = len(cnts)-1
num = math.ceil(lines/3)
print(num)
# Save and show output
im=cv2.cvtColor(im,cv2.COLOR_GRAY2BGR)
cv2.imwrite(sys.path[0]+'/1_.jpg',np.vstack((org,im)))
Note that the edges of your two test_cases are different and appear to be of two different types. So it is normal that you can not handle all the different samples with a simple algorithm. Examine the ideas, change the parameters, add new ideas until you finally get the desired result.
Output image:
Output number is 8 for this testcase.
Finally, I think if you can put the pieces together cleanly (close the gap between them) and always shoot from a fixed angle with a fixed camera and the same amount of light, you might be able to achieve a better result.