Detecting and Extracting Rectangular based Structure

asked 2016-12-01 04:20:51 -0500

AmerSaf gravatar image

I am currently working on a python script to extract specific rectangular feature from an image that has multiple objects.

I would like to extract each object individually as seen below. The problem I am having is that my code works onlly on clear images with no background noise and high resolution. The image on the right does not get detected at all for some reason as its noisier, the edges are rough and it's lower resolution image.

Appreciate any help I can get with this.

image description

import numpy as np
import cv2 
from matplotlib import pyplot as plt
import os


mypath='path\\images'
onlyfiles = [ f for f in os.listdir(mypath) if os.path.isfile(os.path.join(mypath,f)) ]
images = np.empty(len(onlyfiles), dtype=object)
for n in range(0, len(onlyfiles)):
   images[n] = cv2.imread( os.path.join(mypath,onlyfiles[n]) )

   gwash = images[n] #import image

   gwashBW = cv2.cvtColor(gwash, cv2.COLOR_RGB2GRAY) #change to grayscale

   height = np.size(gwash, 0)
   width = np.size(gwash, 1)

   ret,thresh1 = cv2.threshold(gwashBW ,41,255,cv2.THRESH_BINARY) 


   kernel = np.ones((1,1),np.uint8) 

   erosion = cv2.erode(thresh1, kernel,iterations = 31) 
   opening = cv2.morphologyEx(erosion, cv2.MORPH_OPEN, kernel)
   closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel) 

   _,contours, hierarchy = cv2.findContours(closing,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 

   areas = [] #list to hold all areas

  for i,contour in enumerate(contours):
      ar = cv2.contourArea(contour)
      areas.append(ar)
      cnt = contour
      (x, y, w, h) = cv2.boundingRect(cnt)
       if cv2.contourArea(cnt) > 60000 and cv2.contourArea(cnt) < (height*width):
          if hierarchy[0,i,3] == -1:
             cv2.rectangle(gwash, (x,y), (x+w,y+h), (255, 0, 0), 12)


  plt.subplot2grid((2,5),(0,n)),plt.imshow(gwash)
  plt.title('Extraction'), plt.xticks([]), plt.yticks([])


plt.show()
edit retag flag offensive close merge delete

Comments

1

try to blur the Image before you extract your contours, that should reduce the noise of the Image. Try to play with GaussianBlur for example.

Vintez gravatar imageVintez ( 2016-12-01 04:31:54 -0500 )edit

Vintez. Thanks for your reply. I will try the Gaussian Blur effect for noise removal. I also want advice on whether this is the best method to detect such object in the image. What about colorspace segmentation approach

AmerSaf gravatar imageAmerSaf ( 2016-12-01 05:20:47 -0500 )edit
1

A few comments: - Smoothening your image is always a good idea to reduce noise (use e.g. GaussianBlur or defocus your camera) - When detecting objects via color the HSV color space is much more useful than RGB - You process an erosion, opening and closing. An opening processes an erosion and then a dilation. A closing does this the other way round, like dilation and then an erosion. For example if you want to seperate objects which touch each other you can make an erosion and they won't touch anymore but the size of the objects gets smaller. If you compute an opening, you can seperate the objects without bigger effects on their shape. The closing can be used to remove gaps in your object without taking effect to the object's shape.

Hope that I could offer some help to you :)

Flo gravatar imageFlo ( 2016-12-02 06:22:06 -0500 )edit

Unfortunately colorspace approach does not work as I have multiple images with different colors. None of the methods seems to be perfect in isolating the object of interest. I can share the images. Appreciate if further advice can be provided on the code and the approach. I can share more images if required.

AmerSaf gravatar imageAmerSaf ( 2016-12-11 00:51:53 -0500 )edit