Home > Software design >  Finding the centre coordinates in an image of colored points
Finding the centre coordinates in an image of colored points

Time:12-30

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)
  • Related