python - 查找给定颜色的像素的平均位置
问题描述
我正在制作一个自动曲线检测程序(图形、2D 图等),并且一直在试图找到一种颜色的平均位置。颜色是根据 K 均值聚类确定的,因此我有该颜色的 RGB 值。我还构建了一个小型滑动窗口程序来跟踪一组(X,Y)坐标,并且在该窗口中需要找到特定颜色的平均位置/质心。我对 OpenCV 很陌生,所以我将在下面详细说明我想做的事情,并感谢任何帮助。
- 使用 K-means 找到 3 种最常见的颜色,并获得这些颜色的 RGB 值(完成)。
- 使用滑动窗口建立一个 N x N 搜索窗口,该窗口沿着确定的 X、Y 路径行驶(完成)。
- 应用蒙版以获取在搜索窗口中提取的曲线颜色(基于 Kmeans)(需要帮助)。还可能会根据 Kmeans 屏蔽背景颜色。
- 在 NxN 搜索窗口中找到所需曲线颜色的平均 X、Y 坐标/像素位置(需要帮助)。
如果有人可以根据 OpenCV 中的 RGB 值帮助屏蔽图像的颜色,然后在搜索窗口中确定所需颜色的平均像素位置,我们将不胜感激。我已经包含了到目前为止的代码。边界将来自 K-means 聚类,但现在它们只是硬编码用于测试目的。
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)
解决方案
推荐阅读
- python-3.x - 如何为 python3 安装 pyobjc?
- python - 具有原始规范 Python 的模拟类
- ios - 如何从 SceneKit 的坐标绘制 2D UIView?
- sql - 如何查询 DNN (DotNetNuke) 数据库以查找最近修改过的页面
- scala - 使用 mapWithState Spark Streaming 过滤部分重复项
- java - 测量服务器响应 GET 请求所花费的时间
- dart - 如何更改下拉列表中一个复选框的状态?
- java - 如何使用我现有的 Web 项目实现数字签名
- android - 添加后数据消失(MPAndroidChart)
- c++ - 在远程服务器上接收 Gstreamer 流,并保存到磁盘