I'm working on finding coordinates using color, let's say blue in my case, and giving out the coordinates of that point in the image which has that color.
I'm using this code:
#!/usr/bin/env python3
import cv2
import numpy as np
#Load image
img = cv2.imread('image.png')
#Define the blue color we want to find
blue = [255,0,0]
#Get X and Y cooridinates of ALL blue pixels
X,Y = np.where(np.all(img==blue, axis=2))
zipped = np.column_stack((X,Y))
#Get the number of coordinates founded
print(len(zipped))
I'm getting all the pixels colored in the blue region while I'm in need of just one coordinate in that specific location.
This image contains image_with_blue_coordinates the coordinates in blue (but every blue point contains at least 6-to-8 blue pixels) so I'm getting all of the coordinates, while I need just the center pixel.
Any idea on how to deal with this issue and get only 36 x,y coordinates instead of 1342?
Thanks in advance
Reference : Find the coordinates in an image where a specified colour is detected
CodePudding user response:
Well I find another solution using Kmeans, in case anyone needs it here's the code
import cv2
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# Load image
im = cv2.imread('image.png')
# Define the blue colour we want to find - remember OpenCV uses BGR ordering
blue = [255,0,0]
# Get X and Y coordinates of all blue pixels
X,Y = np.where(np.all(im==blue,axis=2))
zipped = np.column_stack((X,Y))
print(len(zipped))
sil = []
kmax = 40
# dissimilarity would not be defined for a single cluster, thus, minimum number of clusters should be 2
for k in range(2, kmax 1):
kmeans = KMeans(n_clusters = k).fit(zipped)
labels = kmeans.labels_
sil.append(silhouette_score(zipped, labels, metric = 'euclidean'))
ind = sil.index(max(sil))
n_points = list(range(2, kmax 1))[ind]
print(n_points)
kmeans = KMeans(n_clusters=n_points).fit(zipped)
points = kmeans.cluster_centers_
print(len(points))
CodePudding user response:
A much faster and better approach using DFS here's the code:
import cv2
import numpy as np
dx=[0,0,1,1,-1,-1]
dy=[1,-1,1,-1,1,-1]
visited={}
def dfs(x, y):
visited[(x,y)]=2
i=0
while i<6:
new_x=x dx[i]
new_y=y dy[i]
if(not((new_x,new_y)in visited)):
i =1
continue
if(visited[(new_x,new_y)]==2):
i =1
continue
dfs(new_x,new_y)
i =1
# Load image
im = cv2.imread('image.png')
# Define the blue colour we want to find - remember OpenCV uses BGR ordering
blue = [255,0,0]
# Get X and Y coordinates of all blue pixels
X,Y = np.where(np.all(im==blue,axis=2))
zipped = np.column_stack((X,Y))
for pixel in zipped:
x=pixel[0]
y=pixel[1]
visited[(x,y)]=1
result=[]
for pixel in zipped:
x=pixel[0]
y=pixel[1]
if visited[(x,y)]==1:
result.append((x,y))
dfs(x,y)
print(result)