Object Detection: Due to the color or transparency of the items, the borders are not accurately detected using the background subtraction method.
Measurements: This inaccuracy leads to incorrect Feret diameter measurements.
Hello everyone,
I’m working on a project where I need to detect and measure items in images. Each image contains a picture of an item, and I’m using the **subtraction **method in OpenCV (cv2) to remove the background and then using the imea library to calculate the maximum and minimum Feret diameters. However, I’m facing challenges with detecting the borders of the items, particularly due to their color or transparency.
Here is the code that I’m using (I’m running this in a Jupyter Notebook):
import cv2 as cv
import os
import numpy as np
import matplotlib.pyplot as plt
from imea.measure_2d.statistical_length import feret
# Function to display images in Jupyter
def display_image(image, title='Image'):
plt.figure(figsize=(10, 10))
plt.imshow(cv.cvtColor(image, cv.COLOR_BGR2RGB))
plt.title(title)
plt.axis('off')
plt.show()
# Path to the current directory and the background image
image_folder = '.'
background_image_path = 'Main.jpeg'
# Load the background image
background_image = cv.imread(background_image_path, cv.IMREAD_COLOR)
if background_image is None:
print(f"Unable to load background image: {background_image_path}")
exit(1)
# Iterate through each file in the current directory
for filename in os.listdir(image_folder):
if filename.endswith('.jpeg') and filename != 'Main.jpeg':
image_path = os.path.join(image_folder, filename)
# Load the current image
image = cv.imread(image_path, cv.IMREAD_COLOR)
if image is None:
print(f"Unable to load image: {image_path}")
continue
# Perform background subtraction
fgMask = cv.absdiff(background_image, image)
# Convert to grayscale for thresholding (if needed)
fgMask_gray = cv.cvtColor(fgMask, cv.COLOR_BGR2GRAY)
# Apply a threshold to get the binary image
_, fgMask_binary = cv.threshold(fgMask_gray, 50, 255, cv.THRESH_BINARY)
# Ensure binary mask is of dtype 'bool'
fgMask_binary = fgMask_binary.astype(bool)
# Display the original image and the foreground mask
display_image(image, title='Original Image')
display_image(fgMask_binary, title='Foreground Mask')
# Calculate Feret diameters using imea library
feret_diameter, idx_x = feret(fgMask_binary)
# Print the results for the current image
print(f"Filename: {filename}, Feret Diameter: {feret_diameter}")
# Pause to control the display in the notebook
input("Press Enter to continue...")
# Clean up
plt.close('all')
Main(Background)
sample
sample
sample
Current Output
Are there alternative methods or preprocessing steps in OpenCV that could help in better isolating the items from the background?
Any advice, suggestions, or guidance on how to tackle these issues would be greatly appreciated. Thank you!
Agura is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.