Ask Your Question
0

findContour() detect unintended internal edges and calculates area wierd for them

asked 2018-08-29 07:08:03 -0600

MikeLemon gravatar image

Hello,

I'm not sure what is going on here but when I use the findContours() function using the cv2.RETER_EXTERNAL on this image:

image description

it still seem to detect inside contours and calculates the area of them wierdly which prevents me from filtering the unwanted contours....

Any clue to why is that?

Here is the original and dialated tresh images:

Original Dialated

here's the code so far:

import cv2
import PIL
import numpy as np
import imutils
imgAddr = "ADisplay2.jpg"

cropX = 20
cropY = 200
cropAngle = 2

CropIndex = (cropX, cropY, cropAngle)

img = cv2.imread(imgAddr)
cv2.imshow("original image",img)



(h, w) = img.shape[:2]
(cX, cY) = (w / 2, h / 2)

# rotate our image by 45 degrees
M = cv2.getRotationMatrix2D((cX, cY), -1.2, 1.0)
rotated = cv2.warpAffine(img, M, (w, h))
#cv2.imshow("Rotated by 45 Degrees", rotated)

cropedImg = rotated[300:700, 100:1500]

# grab the dimensions of the image and calculate the center of the image


#cv2.imshow("croped img", cropedImg)

grayImg = cv2.cvtColor(cropedImg, cv2.COLOR_BGR2GRAY)
#cv2.imshow("gray scale image", grayImg)

blurredImg = cv2.GaussianBlur(grayImg, (9, 9), 0)
cv2.imshow("Blurred_Img", blurredImg)

(T, threshInvImg) = cv2.threshold(blurredImg, 0, 255,
    cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
cv2.imshow("ThresholdInvF.jpg", threshInvImg)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,19))
#opening = cv2.morphologyEx(threshInvImg, cv2.MORPH_OPEN, kernel)
#cv2.imshow("openingImg", opening)

dialeteImg = cv2.morphologyEx(threshInvImg, cv2.MORPH_DILATE, kernel)
cv2.imshow("erodeImg", dialeteImg)

cannyImg =  cv2.Canny(dialeteImg, 100,200)
cv2.imshow("Canny_img", cannyImg)

hierarchy,cntsImg,_ = cv2.findContours(cannyImg,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#print("Img cnts: {}".format(cntsImg))
#print("Img hierarchy: {}".format(hierarchy))


txtOffset = (25, 50)

for cntIdx, cnt in enumerate(cntsImg):
    cntArea = cv2.contourArea(cnt)
    print("Area of contour #{} = {}".format(cntIdx, cntArea))
        (x, y, w, h) = cv2.boundingRect(cnt)
    cv2.rectangle(cropedImg, (x, y), (x + w, y + h), (0, 255, 0), 2)
    txtIdxPos = [x,y]
    txtPos = ((txtIdxPos[0] + txtOffset[0]), (txtIdxPos[1] + txtOffset[1]))
    cv2.putText(cropedImg, "#{}".format(cntIdx), txtPos, cv2.FONT_HERSHEY_SIMPLEX, 1.25, (0, 0, 255), 4)





cv2.imshow("drawCntsImg.jpg", cropedImg)

cv2.waitKey(0)

Thanks for helping :D

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2018-08-31 03:25:13 -0600

Ziri gravatar image

You don't have to use :

cannyImg =  cv2.Canny(dialeteImg, 100,200)

Just find contours in the binary image then filter boxes using area...

edit flag offensive delete link more

Question Tools

3 followers

Stats

Asked: 2018-08-29 07:08:03 -0600

Seen: 337 times

Last updated: Aug 31 '18