2

I'm trying to segregate a tower from its background. To do this I've defined an upper and lower limit HSV range of object color as shown below, but it only segregates partial object from its background, as the object has shades of two different colors, which are grey and white. Is there a possible way to segregate an object containing two different shade colors?

The image is

[![enter image description here][1]][1]

and the code I'm using is:

img = cv2.imread(r'source_img.jpg')
low = np.array([0,0,40])
high = np.array([180,18,230])
hsv = cv2.cvtColor(img,cv2.COLOR_RGB2HSV)
mask = cv2.inRange(hsv,low,high)
masked_img = cv2.bitwise_and(hsv,hsv,mask=mask)

The resultant output image contains only partial object segregation. I want to segregate the full tower excluding background grass, building and sky.

How can I segregate only the object tower without any background?

godzillabeast
  • 155
  • 11
  • that's not trivial. How many images do you have to process in which necessary quality? Maybe is is easier to let a human draw the foreground masks, since the polygon border is quite simple. – Micka May 09 '22 at 11:37
  • 1
    This question was just closed as a duplicate by nathancy: https://stackoverflow.com/questions/72166628/how-to-segregate-object-from-its-background-in-opencv. There were many posts linked with it. – Jeru Luke May 09 '22 at 11:51
  • Does this answer your question? [How to segregate object from its background in opencv?](https://stackoverflow.com/questions/72166628/how-to-segregate-object-from-its-background-in-opencv) – Christoph Rackwitz May 10 '22 at 11:16

1 Answers1

1

HSV color thresholding + two stage morphological operations

Binary image obtained from HSV color thresholding with this lower/upper range

lower = np.array([0, 0, 44])
upper = np.array([82, 78, 227])

There's unwanted contours, so do morph open. Depending on the image you may need to adjust the kernel size or the number of iterations.

Result

import numpy as np
import imutils
import cv2

# Load image, resize smaller, HSV color threshold
image = cv2.imread('1.jpeg')
image = imutils.resize(image, width=600)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 44])
upper = np.array([82, 78, 227])
mask = cv2.inRange(hsv, lower, upper)

# Remove small noise on mask with morph open
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=3)
smooth_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
opening = cv2.morphologyEx(opening, cv2.MORPH_OPEN, smooth_kernel, iterations=3)
result = cv2.bitwise_and(image, image, mask=opening)
# result[opening==0] = (255,255,255) # Optional for white background 

cv2.imshow('result', result)
cv2.imshow('mask', mask)
cv2.imshow('opening', opening)
cv2.waitKey()

Note: Lower/upper HSV ranges were obtained from choosing the correct upper and lower HSV boundaries for color detection with cv::inRange (OpenCV)

nathancy
  • 42,661
  • 14
  • 115
  • 137