My task is to get the x,y coordinates from the segmented image(blue dots) as produced by the code. How do I automate this process? My end results should be a zip of x,y coordinates of these blue dots as produced in the second image.
Code to generate the blue points:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# import cv2_imshow
# from google.colab.patches import cv2_imshow
image = cv2.imread('./S3/frame35.jpg')
#cv2_imshow(image)
result = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# lower boundary RED color range values; Hue (0 - 10)
lower1 = np.array([0, 100, 20])
upper1 = np.array([10, 255, 255])
# upper boundary RED color range values; Hue (160 - 180)
lower2 = np.array([160,100,20])
upper2 = np.array([179,255,255])
lower_mask = cv2.inRange(image, lower1, upper1)
upper_mask = cv2.inRange(image, lower2, upper2)
full_mask = lower_mask + upper_mask;
result = cv2.bitwise_and(result, result, mask=full_mask)
plt.figure(figsize=[20,20])
plt.axis("off")
# plt.subplot(121);plt.imshow(image[:,:,::-1]);plt.title("Original Image",fontdict={'fontsize': 25});plt.axis('off');
plt.subplot(122);plt.imshow(result, cmap='gray');plt.title("Mask of red Color",fontdict={'fontsize': 25});plt.axis('on');
plt.savefig('mask_1.jpg', bbox_inches = 'tight')
# cv2_imshow(full_mask)
# cv2_imshow(result)
#print(full_mask)
#print(result)
cv2.waitKey(0)
cv2.destroyAllWindows()
This is rather straightforward to do by computing the connected components of a binary image.
First you'd have to threshold your image to get a binary image that segments the dots. You can do this for instance with cv2.threshold
. Then you can use cv2.connectedComponentsWithStats
, this will - among other things - return a list of the centroids for all the components. One of them will be the background though, but among the returned values there is an integer arrray of the same size where all components have a different label. So you can look up the label of the component of the background and remove that from the centroid coordinates.
EDIT: The code you added does not even run, but I feed it your second screenshot as a mask.png
and use the mentioned commands as follows, and the plot the centroids
over the image:
src = cv2.imread('mask.png')
_, thresh = cv2.threshold(src[:, :, 0:1], 120, 255, cv2.THRESH_BINARY)
_, _, _, centroids = cv2.connectedComponentsWithStats(thresh, 8, cv2.CV_32S)
EDIT2: Appending following snipped to your newest version results in this:
_, thresh = cv2.threshold(result[:, :, 0:1], 20, 255, cv2.THRESH_BINARY)
_, _, _, centroids = cv2.connectedComponentsWithStats(thresh, 8, cv2.CV_32S)
plt.imshow(thresh)
plt.plot(centroids[:,0], centroids[:, 1], 'or', mfc='none')
plt.show()
The final code with all the above-suggested changes has been implemented below. Using the median filter before the threshold, I am able to limit the number of contours detected. Next I am able to access the specific x,y coordinates by using the index values.
import cv2
import numpy as np
import matplotlib.pyplot as plt
# import cv2_imshow
# from google.colab.patches import cv2_imshow
image = cv2.imread('./S3/frame35.jpg')
#cv2_imshow(image)
result = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# lower boundary RED color range values; Hue (0 - 10)
lower1 = np.array([0, 100, 20])
upper1 = np.array([10, 255, 255])
# upper boundary RED color range values; Hue (160 - 180)
lower2 = np.array([160,100,20])
upper2 = np.array([179,255,255])
lower_mask = cv2.inRange(image, lower1, upper1)
upper_mask = cv2.inRange(image, lower2, upper2)
full_mask = lower_mask + upper_mask;
result = cv2.bitwise_and(result, result, mask=full_mask)
plt.figure(figsize=[20,20])
plt.axis("off")
# plt.subplot(121);plt.imshow(image[:,:,::-1]);plt.title("Original Image",fontdict={'fontsize': 25});plt.axis('off');
plt.subplot(122);plt.imshow(result, cmap='gray');plt.title("Mask of red Color",fontdict={'fontsize': 25});plt.axis('on');
# plt.savefig('mask_1.jpg', bbox_inches = 'tight')
median = cv2.medianBlur(result,9)
_, thresh = cv2.threshold(median[:, :, 0:1],20, 255, cv2.THRESH_BINARY)
_, _, _, centroids = cv2.connectedComponentsWithStats(thresh, 8, cv2.CV_32S)
plt.imshow(thresh)
plt.plot(centroids[:,0], centroids[:, 1], 'or', mfc='none')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
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.