Reputation: 1552
I'm trying to detect the contour of this image in order to crop it in openCV.
I've come up with working code, however, if there is some slight background on the image, it will fail.
Image processing:
Detect boundaries (blue dots):
Crop/rotate:
However, with an image like this, with some background light, it wouldn't work:
preprocess:
Boundaries detection:
def preProcessing(img):
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
adaptive_thresold1 = 31
adaptive_thresold2 = 7
blur = cv2.blur(imgGray, (3, 3))
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,adaptive_thresold1,adaptive_thresold2)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
stackedImages = hp.stackImages(0.1,([img,thresh, close],[img,thresh, close]))
cv2.imshow("WorkFlow", stackedImages)
cv2.waitKey(0)
return thresh
def getContours(img):
biggest = np.array([])
maxArea = 0
img = cv2.bitwise_not(img)
contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in contours:
area = cv2.contourArea(cnt)
if area>5000:
print (area)
#cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3)
peri = cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,0.02*peri,True)
if area >maxArea and len(approx) == 4:
biggest = approx
maxArea = area
print ("ok")
print (biggest)
out = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
cv2.drawContours(out, biggest, -1, (255, 0, 0), 50)
stackedImages = hp.stackImages(0.1,([img,out],[img,out]))
cv2.imshow("WorkFlow", stackedImages)
cv2.waitKey(0)
return biggest
Any suggestion to make this code more reliable ?
Upvotes: 0
Views: 356
Reputation: 1420
Instead of using adaptive thresholding, try using Otsu's thresholding.
Change this line
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,adaptive_thresold1,adaptive_thresold2)
in your code to -
retval_blue, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
This worked for me in the image.
Upvotes: 1