2017-07-21 2 views
2

Ich bin auf der Suche nachVorlage mit zwei Bildern passend, die in der Farbe unterscheiden

1: eine Schaltfläche erfassen

2: bestimmen einen Gewinner basierend auf Farbe der Schaltfläche

Es scheint, als Template-Matching ist, was ich tun sollte, aber das funktioniert in Graustufen. Die Tasten sind grün und rot, sehen aber bei Graustufen ziemlich identisch aus. Meine Idee war, wenn ich zwei Farbkanäle aus dem Bild und den beiden Templates subtrahiere, dass, wenn ich alles in Graustufen umwandele, die beiden Template-Bilder anders aussehen und zu divergierenden Scores führen.

In der Praxis funktioniert es nicht wirklich so. Ich habe ziemlich viel damit experimentiert und entweder beide Vorlagen sehr hoch, oder sie erkennen die Taste überhaupt nicht richtig. Ich kann keine Divergenz bekommen.

Ich bin neu zu OpenCV, so ist es möglich, dass mein Ansatz einfach nicht gut ist. Es ist genauso wahrscheinlich, was ich schreibe, nicht das zu tun, was ich denke. Lass mich wissen was du denkst. Ich habe meinen Code und die Quellbilder, die ich verwende, eingefügt.

import cv2 
import numpy as np 
from matplotlib import pyplot as plt 

dire = cv2.imread('dire.jpg') 
dire_template = cv2.imread('dire_template.jpg') 
radiant = cv2.imread('radiant.jpg') 
radiant_template = cv2.imread('radiant_template.jpg') 

# color images are in the form BGR 
# removing the B and G from the images makes the "continue" button more distinct between the two teams 
# since dire is red while radiant is green 
dire_red = dire.copy() 
dire_red[:,:,0] = 0 
dire_red[:,:,1] = 0 

dire_template_red = dire_template.copy() 
dire_template_red[:,:,0] = 0 
dire_template_red[:,:,1] = 0 

radiant_red = radiant.copy() 
radiant_red[:,:,0] = 0 
radiant_red[:,:,1] = 0 

radiant_template_red = radiant_template.copy() 
radiant_template_red[:,:,0] = 0 
radiant_template_red[:,:,1] = 0 


dire_gray = cv2.cvtColor(dire_red, cv2.COLOR_BGR2GRAY) 
dire_template_gray = cv2.cvtColor(dire_template_red, cv2.COLOR_BGR2GRAY) 
radiant_gray = cv2.cvtColor(radiant_red, cv2.COLOR_BGR2GRAY) 
radiant_template_gray = cv2.cvtColor(radiant_template_red, cv2.COLOR_BGR2GRAY) 

# plt.figure(0) 
# plt.imshow(dire_red) 
# plt.figure(1) 
# plt.imshow(radiant_red) 
# plt.figure(2) 
# plt.imshow(dire_gray, cmap='gray') 
# plt.figure(3) 
# plt.imshow(radiant_gray, cmap='gray') 
# plt.figure(4) 
# plt.imshow(dire_template_red) 
# plt.figure(5) 
# plt.imshow(radiant_template_red) 
# plt.figure(6) 
# plt.imshow(dire_template_gray) 
# plt.figure(7) 
# plt.imshow(radiant_template_gray, cmap='gray') 

# plt.show() 

w, h = dire_template_gray.shape[::-1] 

# All the 6 methods for comparison in a list 
methods = ['cv2.TM_CCOEFF_NORMED', 
      'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF_NORMED'] 

for meth in methods: 
    print(f'{meth}: ') 
    # this would be the live image 
    img = dire_gray.copy() 
    method = eval(meth) 

    # Apply template Matching 
    dire_res = cv2.matchTemplate(img,dire_template_gray,method) 
    radiant_res = cv2.matchTemplate(img,radiant_template_gray,method) 


    dire_vals = [min_val, max_val, min_loc, max_loc] = cv2.minMaxLoc(dire_res) 
    radiant_vals = [min_val, max_val, min_loc, max_loc] = cv2.minMaxLoc(radiant_res) 

    print(dire_vals) 
    print(radiant_vals) 
    # print(f'min val: {min_val} max val: {max_val}') 

    # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum 
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]: 
     top_left = min_loc 
    else: 
     top_left = max_loc 
    bottom_right = (top_left[0] + w, top_left[1] + h) 

    cv2.rectangle(img,top_left, bottom_right, 255, 2) 

    # plt.subplot(121),plt.imshow(res,cmap = 'gray') 
    plt.subplot(121),plt.imshow(dire_res) 
    plt.title('Matching Result'), plt.xticks([]), plt.yticks([]) 
    # plt.subplot(122),plt.imshow(img,cmap = 'gray') 
    plt.subplot(122),plt.imshow(img) 
    plt.title('Detected Point'), plt.xticks([]), plt.yticks([]) 
    plt.suptitle(meth) 

    plt.show() 

radiant.jpg dire.jpg radiant_template.jpg enter image description here

+0

Suchen Sie den Ort in Graustufen.Sobald Sie wissen, wo der Knopf ist, gehen Sie zurück zu BGR (oder sogar HSV) und bestimmen Sie die Farbe. –

+0

Möchten Sie beide Schaltflächen mit demselben Code erkennen oder möchten Sie sie unterscheiden? Wie sieht es mit der Formanpassung der Kanten aus wie Fasenanpassung? – Micka

Antwort

1

Ihr Ansatz scheint genau, wie Sie es Implementierung sein sollte. Ich habe den gleichen Ansatz und das ist mein Ergebnis:

Schritt 1: Laden Sie Bilder in Farbe und Grau

img_red = cv2.imread("red.jpg") 
img_red_gray = cv2.cvtColor(img_red, cv2.COLOR_BGR2GRAY) 

img_green = cv2.imread("green.jpg") 
img_green_gray = cv2.cvtColor(img_green, cv2.COLOR_BGR2GRAY) 

// template is required only in gray 
template = cv2.imread("template.jpg", 0) 

2 Schritt skaliert bekommen: Größe der Vorlage erhalten und mit dem Template passenden

w, h = template.shape[::-1] 
method = cv2.TM_CCOEFF 
res = cv2.matchTemplate(img_red_gray, template, method) 

Schritt 3: Vorlage Lage in Bild erhalten und seine mittlere Farbintensität

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) 
top_left = max_loc 
color = cv2.mean(img_red[top_left[1]:top_left[1] + h, top_left[0]:top_left[0]+w]) 

Gelangen itional: Um das Spiel im Haupt Bild zeichnen

bottom_right = (top_left[0] + w, top_left[1] + h) 
cv2.rectangle(img_red_gray, top_left, bottom_right, 255, 2) 

Ergebnisse:

Template in Green

Template in Red

Red Bildfarbe = (5.1372107567229515, 12.502939337085678, 72.62376485303315, 0.0)(B, G, R, A)

Grün Bildfarbe = (63.20187617260788, 85.38574108818011, 49.76873045653534, 0.0)(B, G, R, A)

Wie @Dan vorgeschlagen, können Sie dies auch in HSV tun, um höhere Unterschiede zu erhalten.

Sie können deutlich sehen, dass Sie jetzt mit den einzelnen Kanalwerten sagen können, ob die Vorlage im Bild grün oder rot ist. Hoffe es hilft!

Verwandte Themen