简体   繁体   中英

How Can I Detect If There are Secondary Objects in an Image

I am looking for a way to detect if there are secondary objects in an image or if the image just has the one main object. I've done a bit of research, but I haven't been able to find anything quite like what I am looking for.

An example image would be:

The main object being the two detergent bottles since they overlap and the secondary object would be the "2 pack" pop up bubble in the top right. I would expect this image to return something like: "This image has secondary objects" or a count of the objects.

Here is one way to do that in Python/OpenCV

  • Read the input
  • Convert to gray and invert
  • OTSU threshold
  • Morphology close
  • Get external contours
  • Draw contours on image
  • Count contours
  • Print messages
  • Save results

Input:

在此处输入图像描述

import cv2
import numpy as np

# read image
img = cv2.imread("tide.jpg")

# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# invert gray image
gray = 255 - gray

# threshold gray image
#thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

# apply morphology close
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# Get contours
cntrs = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
result = img.copy()
for c in cntrs:
    cv2.drawContours(result, [c], -1, (0,0,255), 1)

count = len(cntrs)
print("")
print("count =",count)

print("")

if count > 1:
    print("This image has secondary objects")
else:
    print("This image has primary object only")

# write results to disk
cv2.imwrite("tide_thresh.png", thresh)
cv2.imwrite("tide_morph.png", morph)
cv2.imwrite("tide_object_contours.png", result)

# display it
cv2.imshow("thresh", thresh)
cv2.imshow("morph", morph)
cv2.imshow("result", result)
cv2.waitKey(0)


Thresholded image:

在此处输入图像描述

Morphology close image:

在此处输入图像描述

Contours on image:

在此处输入图像描述

Count of contours and messages:

count = 2

This image has secondary objects


Following @fmw42's advice, I did a bit of research and found a script that worked well after a little bit of tinkering:

import cv2
import numpy as np
import sys


img = cv2.imread(sys.argv[1], cv2.IMREAD_UNCHANGED)

#convert img to grey
img_grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#set a thresh
thresh = 230
#get threshold image
ret,thresh_img = cv2.threshold(img_grey, thresh, 255, cv2.THRESH_BINARY_INV)
#find contours
contours, hierarchy = cv2.findContours(thresh_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

#create an empty image for contours
# img_contours = np.zeros(img.shape)
img_contours = np.zeros_like(img)
# draw the contours on the empty image
cv2.drawContours(img_contours, contours, -1, 255, 3)
#save image
cv2.imshow('contours',img_contours)
# Wait indefinitely until you push a key.  Once you do, close the windows

print len(contours)

cv2.waitKey(0)
cv2.destroyAllWindows()

My main issue was the threshold setting and I found that 230 worked best with my sample images, although it still is not perfect. I'm hoping there is a better way or something I can add to this.

this image returned 1 as expected, but my initial test image returns 3 at this threshold setting when I would expect 2. At 200 thresh it returns 2, but I was willing to compromise because the main thing I need to know is if it is more than 1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM