2

after applied cv morph transformations I ended up with the following binay image:

enter image description here

As you can see, there's a big rect in the middle and a second tighter rect on the right. I would like to know which may be a good way to identify and crop the rect on the right, in order to achieve something like that:

enter image description here

Thank you

Michele
  • 95
  • 8

1 Answers1

0

After some searches i ended up with a possible solution. The key issue was to perform a correct image pre-processing in order to achieve solid lines (as opposed to the image in the question: we need lines without gaps).

This post has been life-saving: Gap Filling Contours / Lines. For my purpose, dimKernel=50, thBin=160, thDistTrans=0.07

def preprocessing(imm,dimKernel,thBin,thDistTrans):
  grayImage = cv.cvtColor(imm, cv.COLOR_BGR2GRAY)
  ret,binImage=cv.threshold(grayImage,thBin,255,cv.THRESH_BINARY_INV)

  structVerticale = kernelVerticale(dimKernel,1)
  im1 = cv.morphologyEx(binImage, cv.MORPH_OPEN, structVerticale)
  structOrizzontale = kernelOrizzontale(dimKernel,3)
  im2 = cv.morphologyEx(binImage, cv.MORPH_OPEN, structOrizzontale)

  result = overlaps(im1,im2)  
  out = ndi.distance_transform_edt(np.invert(result))
  out = out < thDistTrans * out.max()
  out = morphology.skeletonize(out)

  out = (out.astype(int)*255).astype("uint8")
  kernel = np.ones((3,3),np.uint8)
  out = cv.dilate(out,kernel)

  return out

Then, I needed to identify the right rect using cv.findContours; from empirical evidences, I understood that the rect I was looking for may be identified using areas (from 1/6 up to 1/3 of the original area image). Finally, the contour has been approximate to rect using cv.boundingRect and then crop:

contours, hierarchy = cv.findContours(ris,cv.RETR_CCOMP , cv.CHAIN_APPROX_SIMPLE)
hierarchy = hierarchy[0]

aree = []
for i,figura in enumerate(contours):
    area = cv.contourArea(figura)
    aree.append([area,i])
aree.sort(reverse=True)

areaMax = (ris.shape[0]*ris.shape[1])/3
areaMin = (ris.shape[0]*ris.shape[1])/6

i = 0
while i<len(aree) and (aree[i][0]<areaMin or aree[i][0]>areaMax):
    i+=1

cnt = contours[aree[i][1]]
x,y,w,h = cv.boundingRect(cnt)

immOrg = immOrg.crop((x, y, x+w, y+h))

I'm sure this solution is far from the optimal solution, as I'm an amateur programmer and I never used cv before, but I hope can help someone

Michele
  • 95
  • 8