Python 查找给定颜色像素的平均位置

Python 查找给定颜色像素的平均位置,python,opencv,computer-vision,Python,Opencv,Computer Vision,我正在制作一个自动曲线检测程序(图形、2D绘图等),一直在努力寻找颜色的平均位置。颜色是基于K均值聚类确定的,所以我有该颜色的RGB值。我还构建了一个小的滑动窗口程序来跟踪一组(X,Y)坐标,在该窗口中,需要找到特定颜色的平均位置/质心。我对OpenCV非常陌生,所以我将在下面详细介绍我想做的事情,并感谢您的帮助 用K-means查找3种最常见的颜色,并获得这些颜色的RGB值(完成) 使用滑动窗口建立沿确定的x,Y路径运行的N x N搜索窗口(完成) 应用遮罩以获取在搜索窗口中提取的曲线颜色(基

我正在制作一个自动曲线检测程序(图形、2D绘图等),一直在努力寻找颜色的平均位置。颜色是基于K均值聚类确定的,所以我有该颜色的RGB值。我还构建了一个小的滑动窗口程序来跟踪一组(X,Y)坐标,在该窗口中,需要找到特定颜色的平均位置/质心。我对OpenCV非常陌生,所以我将在下面详细介绍我想做的事情,并感谢您的帮助

  • 用K-means查找3种最常见的颜色,并获得这些颜色的RGB值(完成)
  • 使用滑动窗口建立沿确定的x,Y路径运行的N x N搜索窗口(完成)
  • 应用遮罩以获取在搜索窗口中提取的曲线颜色(基于Kmeans)(需要帮助)。还可能基于Kmeans屏蔽背景色
  • 在NxN搜索窗口中查找所需曲线颜色的平均X、Y坐标/像素位置(需要帮助)
  • 如果有人能够帮助根据OpenCV中的RGB值屏蔽图像的颜色,然后在搜索窗口中确定所需颜色的平均像素位置,将不胜感激。到目前为止,我已经包含了代码。边界可能来自K-means聚类,但现在它们只是为了测试而硬编码的

    下面是一个曲线示例,我将尝试遵循任何一条黑线


    您可以使用scikit learn kmeans直接获取集群中心。看见同样,在Python/OpenCV中,请参见“请共享与您成功完成的最后一步相对应的图像”以及您必须继续执行下一步的代码。谢谢你。你想沿着黑色实线走,还是灰色虚线走?请问“像素宽像素高”的窗口有多大?@MarkSetchell我想沿着黑线走。理想情况下,窗口将根据线条的宽度进行调整。目前,第一步是单击线上的几个点,然后用ReadCoords加载。然后搜索窗口“移动”该行,并使用kmeans颜色查找像素颜色的平均位置(在本例中为黑色)。您能分享一些您一直使用的合理坐标吗?
    import matplotlib.pyplot as plt 
    import matplotlib.image as mpimg
    import numpy as np 
    import cv2
    import math
    import time
    from tkinter import *
    from tkinter import filedialog
    from tkinter import ttk
    from tkinter.filedialog import askopenfilename
    from tkinter import scrolledtext
    from PIL import Image, ImageTk
    import os
    import ReadCoords
    from sklearn.cluster import KMeans
    
    (winW, winH) = (12,12)
    xs,ys = ReadCoords.read_coords()
    image = cv2.imread(r"Curve.PNG")
    
    
    boundaries = [([0,0,0],[128,128,128])]
    def color_detection(image, boundaries):
      for (lower,upper) in boundaries:
          lower = np.array(lower, dtype = 'uint8')
          upper = np.array(upper, dtype = 'uint8')
    
          mask = cv2.inRange(image, lower, upper)
          output = cv2.bitwise_and(image, image, mask = mask)
          return output
    
    def kmeans_colors(image = image):
        org_clone = image.copy()
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        # image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        image = image.reshape((image.shape[0] * image.shape[1], 3))
        # image = image.reshape((image.shape[0] * image.shape[1], 1))
        clt = KMeans(n_clusters = 3)
        clt.fit(image)
    
        # print(clt.cluster_centers_)
    
        def centroid_histogram(clt):
            # grab the number of different clusters and create a histogram
            # based on the number of pixels assigned to each cluster
            numLabels = np.arange(0, len(np.unique(clt.labels_)) + 1)
            (hist, _) = np.histogram(clt.labels_, bins = numLabels)
    
            # normalize the histogram, such that it sums to one
            hist = hist.astype("float")
            hist /= hist.sum()
    
            # return the histogram
            return hist
    
    
        def plot_colors(hist, centroids):
            # initialize the bar chart representing the relative frequency
            # of each of the colors
            bar = np.zeros((50, 300, 3), dtype = "uint8")
            startX = 0
    
            # loop over the percentage of each cluster and the color of
            # each cluster
            for (percent, color) in zip(hist, centroids):
                # plot the relative percentage of each cluster
                endX = startX + (percent * 300)
                cv2.rectangle(bar, (int(startX), 0), (int(endX), 50),
                    color.astype("uint8").tolist(), -1)
                startX = endX
    
            # return the bar chart
            return bar
    
    
        hist = centroid_histogram(clt)
        bar = plot_colors(hist, clt.cluster_centers_)
    
        return clt.cluster_centers_
    
    
    def curve_sliding_window(image, step_size, window_size, x_range, y_range):
      for x,y in zip(x_range, y_range):
        yield (x, y, image[y:y+window_size[1], x:x+window_size[0]])
    
    
    for (x, y, window) in curve_sliding_window(image, step_size=8, window_size=(winW, winH), x_range = xs, y_range = ys ):
        # if the window does not meet our desired window size, ignore it
        if window.shape[0] != winH or window.shape[1] != winW:
            continue
    
    
        # THIS IS WHERE YOU WOULD PROCESS YOUR WINDOW, SUCH AS APPLYING A
        # MACHINE LEARNING CLASSIFIER TO CLASSIFY THE CONTENTS OF THE
        # WINDOW
    
        # since we do not have a classifier, we'll just draw the window
        clone = image.copy()
        cv2.rectangle(clone, (x, y), (x + winW, y + winH), (0, 0, 255), 2)
        cv2.imshow("Window", clone)
        # cv2.waitKey(1)
        # time.sleep(0.01)
    
        masked = color_detection(window, boundaries)
    
        cX,cY = moment_centriod(contours(window))
    
        if cX != 3 and cY != 3:
            cv2.circle(window, (cX, cY), 1, (0,0,255), 2)
    
        cv2.imshow("windows", np.hstack([masked, window]))
        cv2.waitKey(50)