How to find contour of an image with missing part?
Question:
Grocery bill:
As some of the top and bottom part of the image is missing the biggest contour i.e. the main bill cannot be cropped. The code works well in case of a complete bill image but fails to handle a missing-vertex image.
Code:
imgContours = img.copy() # COPY ORIGNAL IMAGE
imgBigContour = img.copy() # COPY ORIGNAL IMAGE
_, contours,_ = cv2.findContours(imgThreshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # FIND ALL CONTOURS
cv2.drawContours(imgContours, contours, -1, (0, 255, 0), 10) # DRAW ALL DETECTED CONTOURS
# FIND THE BIGGEST COUNTOUR
biggest, maxArea = utlis.biggestContour(contours) # FIND THE BIGGEST CONTOUR
if biggest.size != 0:
biggest=utlis.reorder(biggest)
cv2.drawContours(imgBigContour, biggest, -1, (0, 255, 0), 20) # DRAW THE BIGGEST CONTOUR
imgBigContour = utlis.drawRectangle(imgBigContour,biggest,2)
pts1 = np.float32(biggest) # PREPARE POINTS FOR WARP
pts2 = np.float32([[0, 0],[widthImg, 0], [0, heightImg],[widthImg, heightImg]]) # PREPARE POINTS FOR WARP
matrix = cv2.getPerspectiveTransform(pts1, pts2)
imgWarpColored = cv2.warpPerspective(img, matrix, (widthImg, heightImg))
Answers:
As suggested by one of the person in comments i.e. use cv2.copyMakeBorder()
it worked. So the proper syntax with respect to the above code of reference will be:
img = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_CONSTANT)
actually what it does is that it adds a black border of 10 pixels on each side. And further when we use cv2.findContour()
it actually detects the largest one(including the previous small ones) which wasn’t counted earlier.
Grocery bill:
As some of the top and bottom part of the image is missing the biggest contour i.e. the main bill cannot be cropped. The code works well in case of a complete bill image but fails to handle a missing-vertex image.
Code:
imgContours = img.copy() # COPY ORIGNAL IMAGE
imgBigContour = img.copy() # COPY ORIGNAL IMAGE
_, contours,_ = cv2.findContours(imgThreshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # FIND ALL CONTOURS
cv2.drawContours(imgContours, contours, -1, (0, 255, 0), 10) # DRAW ALL DETECTED CONTOURS
# FIND THE BIGGEST COUNTOUR
biggest, maxArea = utlis.biggestContour(contours) # FIND THE BIGGEST CONTOUR
if biggest.size != 0:
biggest=utlis.reorder(biggest)
cv2.drawContours(imgBigContour, biggest, -1, (0, 255, 0), 20) # DRAW THE BIGGEST CONTOUR
imgBigContour = utlis.drawRectangle(imgBigContour,biggest,2)
pts1 = np.float32(biggest) # PREPARE POINTS FOR WARP
pts2 = np.float32([[0, 0],[widthImg, 0], [0, heightImg],[widthImg, heightImg]]) # PREPARE POINTS FOR WARP
matrix = cv2.getPerspectiveTransform(pts1, pts2)
imgWarpColored = cv2.warpPerspective(img, matrix, (widthImg, heightImg))
As suggested by one of the person in comments i.e. use cv2.copyMakeBorder()
it worked. So the proper syntax with respect to the above code of reference will be:
img = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_CONSTANT)
actually what it does is that it adds a black border of 10 pixels on each side. And further when we use cv2.findContour()
it actually detects the largest one(including the previous small ones) which wasn’t counted earlier.