How can I create bounding boxes/contour around the outer object only - Python OpenCV

2024/11/13 9:24:56

So I've been trying to make bounding boxes around a couple of fruits that I made in paint. I'm a total beginner to opencv so I watched a couple tutorials and the code that I typed made, makes contours around the object and using that I create bounding boxes. However it makes way too many tiny contours and bounding boxes. For example, heres the initial picture: enter image description here

and heres the picture after my code runs: enter image description here

However this is what I want:

enter image description here

Heres my code:

import cv2
import numpy as npimg = cv2.imread(r'C:\Users\bob\Desktop\coursera\coursera-2021\project2\fruits.png')grayscaled = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(grayscaled, (7,7), 1)
canny = cv2.Canny(blur, 50, 50)
img1 = img.copy()
all_pics = []contours, Hierarchy = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for cnt in contours:peri = cv2.arcLength(cnt, True)approx = cv2.approxPolyDP(cnt, 0.02*peri, True)x, y, w, h = cv2.boundingRect(approx)bob = img [y:y+h, x:x+w]all_pics.append((x, bob))cv2.rectangle(img1, (x, y), (x+w, y+h), (0, 255, 0), 2)cv2.imshow("title", img1)
cv2.waitKey(0)
Answer

I think FloodFill in combination with FindContours can help you:

import os
import cv2
import numpy as np# Read original image
dir = os.path.abspath(os.path.dirname(__file__))
im = cv2.imread(dir+'/'+'im.png')# convert image to Grayscale and Black/White
gry = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imwrite(dir+'/im_1_grayscale.png',gry)
bw=cv2.threshold(gry, 127, 255, cv2.THRESH_BINARY)[1]
cv2.imwrite(dir+'/im_2_black_white.png',bw)# Use floodfill to identify outer shape of objects
imFlood = bw.copy()
h, w = bw.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
cv2.floodFill(imFlood, mask, (0,0), 0)
cv2.imwrite(dir+'/im_3_floodfill.png',imFlood)# Combine flood filled image with original objects
imFlood[np.where(bw==0)]=255
cv2.imwrite(dir+'/im_4_mixed_floodfill.png',imFlood)# Invert output colors
imFlood=~imFlood
cv2.imwrite(dir+'/im_5_inverted_floodfill.png',imFlood)# Find objects and draw bounding box
cnts, _ = cv2.findContours(imFlood, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
for cnt in cnts:peri = cv2.arcLength(cnt, True)approx = cv2.approxPolyDP(cnt, 0.02*peri, True)x, y, w, h = cv2.boundingRect(approx)bob = im[y:y+h, x:x+w]cv2.rectangle(im, (x, y), (x+w, y+h), (0, 255, 0), 2)# Save final image
cv2.imwrite(dir+'/im_6_output.png',im)

Grayscale and black/white:

enter image description here

Add flood fill:

enter image description here

Blend original objects with the flood filled version:

enter image description here

Invert the colors of blended version:

enter image description here

Final output:

enter image description here

https://en.xdnf.cn/q/119373.html

Related Q&A

resuming download file ftp python3.*

There is a file (1-7Gb) that you need to pick up. The network periodically falls, so it is necessary to implement the method of resume. For example, in 1 communication session downloaded 20% the networ…

printing files based on character

I have a directory(data) that contain thousand of files.Each time I want to select three files that are just differ by only one characterAB[C,D,E] and want to perform some computation on the selected t…

Parsing CSV file using Panda

I have been using matplotlib for quite some time now and it is great however, I want to switch to panda and my first attempt at it didnt go so well.My data set looks like this:sam,123,184,2.6,543 winte…

Getting division by zero error with Python and OpenCV

I am using this code to remove the lines from the following image:I dont know the reason, but it gives me as output ZeroDivisionError: division by zero error on line 34 - x0, x1, y0, y1 = (0, im_wb.sha…

Pandas complex calculation based on other columns

I have successfully created new columns based on arithmetic for other columns but now I have a more challenging need to first select elements based on matches of multiple columns then perform math and …

how to generate word from a to z [closed]

Its difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying thi…

How to webscrape all shoes on nike page using python

I am trying to webscrape all the shoes on https://www.nike.com/w/mens-shoes-nik1zy7ok. How do I scrape all the shoes including the shoes that load as you scroll down the page? The exact information I …

Pyo in Python: name Server not defined

I recently installed Pyo, and I entered Python 3.6 and typedfrom pyo import * s = Server().boot() s.start() sf = SfPlayer("C:\Users\myname\Downloads\wot.mp3", speed=1, loop=True).out()but I …

Limited digits with str.format(), and then only when they matter

If were printing a dollar amount, we usually want to always display two decimal digits.cost1, cost2 = 123.456890123456789, 357.000 print {c1:.2f} {c2:.2f}.format(c1=cost1, c2=cost2)shows123.46 357.00…

How is covariance implemented internally in numpy?

This is the definition of a covariance matrix. http://en.wikipedia.org/wiki/Covariance_matrix#DefinitionEach element in the matrix, except in the principal diagonal, (if I am not wrong) simplifies to E…