Найти среднее положение пикселя данного цвета - PullRequest
0 голосов
/ 13 января 2020

Я делаю автоматическую c программу для определения кривой (графики, 2D-графики и т. Д. c.) И застрял при попытке найти среднее положение цвета. Цвет определяется на основе K означает кластеризацию, поэтому у меня есть значение RGB для этого цвета. Я также построил небольшую программу скользящего окна, чтобы следовать набору координат (X, Y), и в этом окне нужно найти среднее положение / центр тяжести для определенного цвета. Я очень новичок в OpenCV, поэтому я подробно опишу, что я хочу сделать ниже, и буду благодарен за любую помощь.

  1. Найдите 3 наиболее распространенных цвета с помощью K-средних и получите значения RGB этих цветов (готово).
  2. Используйте скользящее окно, чтобы установить sh окно поиска N x N, которое движется по определенному пути X, Y (готово).
  3. Примените маску, чтобы получить Цвет кривой (на основе Kmeans) извлекается в окне поиска (нужна помощь). Также возможно замаскировать цвет фона на основе Kmeans.
  4. Найти среднюю координату X, Y / положение пикселя для требуемого цвета кривой в окне поиска NxN (нужна помощь).

Было бы полезно, если бы кто-нибудь мог помочь с маскировкой цвета изображения на основе значения RGB в OpenCV, а затем с определением среднего местоположения в пикселях нужного цвета в окне поиска. Я включил код, который у меня есть до сих пор. Границы будут исходить из кластеризации K-средних, но сейчас они просто жестко запрограммированы для целей тестирования.

Ниже приведен пример кривой, где я бы попытался следовать любой из черных линий Curve

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...