I am detecting object silhouettes in front of a light source. To simplify the background and remove noise, I require masking everything that isn't the light source. How can I tell when the object would be on the edge of the masked area?
Assume featureless (monochrome black and white for edge detection) and ambiguous (a square in image 1 may be a circle in image 2) in shape.
Consider a silhouette in front of a light source. It is distinct and we can tell it is nested within the outer contour. Figure 1 depicts a simplified case.
We can treat our outer circle as a mask in this case, and easily ignore everything NOT within the contour. Figure 2 depicts the simplified case with some edge detection.
Everything works lovely until the silhouette moves to the edge of the light source. Suddenly we run into problems. Figure 3 is an example of a shape on the edge.
The silhouette is indistinguishable from the black of the background/masked area. OpenCV either assumes that suddenly the contour of our light source is funny shaped and there is no other object to be detected.
What tools can I use to detect that there has been some sort of interruption of the edge shape? Is there a good/computational cheap way of determining if our silhouette is intersecting with another?
HoughCircles
does not work. You can use the cv2.log_polar
function to unwrap the circle/oval shape.
After that, np.argmax
can be used to find the curve. Try smoothing out the curve using Scipy's signal.savgol_filter()
. When the object blocks the light source, there will be a big difference between the smoothed line and the argmax data:
This is the code that I used:
import numpy as np
import cv2
# Read the image
img = cv2.imread('/home/stephen/Desktop/JkgJw.png', 0)
# Find the log_polar image
log_polar = cv2.logPolar(img, (img.shape[0]/2, img.shape[1]/2), 40, cv2.WARP_FILL_OUTLIERS)
# Create a background to draw on
bg = np.zeros_like(log_polar)
# Iterate through each row in the image and get the points on the edge
h,w = img.shape
points = []
for col in range(h-1):
col_slice = log_polar[col:col+1, :]
curve = np.argmax(255-col_slice)
cv2.circle(bg, (curve, col), 0, 255, 1)
points.append((curve, col))
cv2.imshow('log_polar', log_polar)
cv2.waitKey(0)
cv2.destroyAllWindows()
import scipy
from scipy import signal
x,y = zip(*points)
x_smooth = signal.savgol_filter(x,123,2)
import matplotlib.pyplot as plt
plt.plot(x)
plt.plot(x_smooth)
plt.show()
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.