Problem Statement & Background Info:
EDIT: Constraints: The red coloring on the flange changes over time, so I'm not trying to use color recognition to identify my object at this moment unless it can be robust. Addition,ally external illumination my be a factor since this will be in an outdoor area in the future.
I have RGB-Depth camera and with it, I'm able to capture this scene. Where each pixel (x,y) has a depth value.
Applying a gradient magnitude filter to the depth map associated with my image I'm able to get the following edge map.
The gradient magnitudes are given the value of 0 if they had a magnitude that wasn't zero. Black (255) is for magnitude values associated with 0 (homogenous depth or a flat surface).
From this edge map I dialated the edges so picking up the contours would be easier.
Then I found the contours in the image and tried to plot just the 5 biggest contours.
PROBLEM
Is there a way to reliably find the contours associated with my objects (the red box and metal fixture) and then find their geometric centroid? I keep running into the issue that I can find contours in the image, but I have no way of selectively screening for the contours that are my objects and not noise.
I have provided the image I used for the image processing, but for some reason, OpenCV saves the image as a black image, and when you read it in using...
gray = cv2.imread('GRAYTEST.jpeg', cv2.IMREAD_GRAYSCALE)
it appears blue-ish and not a binary white/black image as I show. So sorry about that.
Sorry, I don't know why it saved just as a black image, but if you read it in OpenCV it should show up with the same lines as "magnitude of gradients" plot.
MY CODE
gray = cv2.imread('GRAYTEST.jpeg', cv2.IMREAD_GRAYSCALE)
plt.imshow(gray)
plt.title('gray start image')
plt.show()
blurred = cv2.bilateralFilter(gray, 8, 25, 25) # blurr image while preserving edges
kernel = np.ones((3, 3), np.uint8) # define a kernel (block) to apply filters to
dialated = cv2.dilate(blurred, kernel, iterations=1)
plt.title('dialated')
plt.imshow(dialated)
plt.show()
#Just performs a canny edge dectection on an image
edges_empty = self.Commons.CannyE_Auto(dialated) # Canny edge image for some sigma
#makes an empty image using the same diemensions of the given image
empty2 = self.Commons.make_empty(gray)
_, contours, _ = cv2.findContours(edges_empty, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(contours, key=cv2.contourArea, reverse=True)[:5] # get largest five contour area
cv2.drawContours(empty2, cnts, -1, (255, 0, 0), thickness=1)
plt.title('contours')
plt.imshow(empty2)
plt.show()