2016-04-06 8 views
1

Wie kann ich die hellgraue Hintergrundfarbe (mit Variationen in den Schattierungen) in eine einzelne Farbe umwandeln, z. B. hellgrau? Ich möchte, dass die dunkelgraue Farbe, die über der Hintergrundfarbe eingebettet ist, auch eine einzelne Farbe hat. Bis jetzt, was ich getan habe, ist, diese zwei Regionen mit zwei nächstliegenden Farbnamen ('lightgray' und 'dimgray') zu belegen und die Summe der quadrierten Differenzen für jedes Pixel r, g, b zu minimieren und die nächste Farbe aus dem Modul zu erhalten .Konvertieren verschiedener Schattierungen einer Farbe in einem Bild in eine Farbe

rd = (r_c - requested_color[0]) ** 2 
gd = (g_c - requested_color[1]) ** 2 
bd = (b_c - requested_color[2]) ** 2 

Originalbild:

enter image description here

Bild von meinem Python-Code erzeugt:

enter image description here

können Sie sehen, dass die entlang der Grenzen Ich bin nicht fähig zu g und die hellgraue Farbe, wie Sie im Originalbild sehen konnten.

Antwort

3

Was Sie tun möchten, heißt Schwellwertbildung. http://docs.opencv.org/3.1.0/d7/d4d/tutorial_py_thresholding.html#gsc.tab=0

Ich habe einige Parameter des Codes dort angepasst:

Eine allgemeine Einführung, wie dies mit OpenCV und Python zu tun, ist hier zu finden

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

img = cv2.imread('image.png',0) 
img = cv2.medianBlur(img,7) 
ret,th1 = cv2.threshold(img,160,255,cv2.THRESH_BINARY) 
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,31,5) 
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,31,5) 
titles = ['Original Image', 'Global Thresholding (v = 127)', 
'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding'] 
images = [img, th1, th2, th3] 
for i in xrange(4): 
    plt.subplot(2,2,i+1),plt.imshow(images[i],'gray') 
    plt.title(titles[i]) 
    plt.xticks([]),plt.yticks([]) 
plt.show() 

Wie Sie in dem resultierenden sehen Bild, das Problem mit Ihrem Bild ist die starke Variation der Hintergrundintensität. Ohne die Herkunft Ihrer Bilder zu wissen, ich mit einem der beiden folgenden Optionen beginnen würde, bevor Sie versuchen diese durch Software zu lösen:

1.)

2.) Falls dies nicht möglich, eine gleichmäßigere Beleuchtung Get und wenn die Beleuchtung für alle Bilder gleich ist, machen Sie nur ein leeres Bild des Hintergrunds und subtrahieren Sie es von Ihren anderen Bildern, um eine gleichmäßigere Beleuchtung zu erhalten.

Es ist wichtig zu verstehen, dass dies kein Softwareproblem ist: In den Randbereichen ist der Hintergrund in der Mitte des Bildes dunkler als die Struktur. Sie können dies überprüfen, indem Sie die Grauwerte einzelner Pixel überprüfen. Nur dein Auge kann das sehr gut kompensieren. Die unten aufgeführten adaptiven Schwellenwertverfahren versuchen, einen geeigneten lokalen Schwellenwert zu finden, aber es gibt eine Grenze dafür. Sie können vielleicht mehr geeignete Parameter finden, aber das erste, was ich empfehlen würde, arbeitet an der Gleichmäßigkeit der Beleuchtung.

enter image description here

[EDIT]

ich ein zusätzliches Stück Code unten hinzugefügt haben, um mit den Bildern zu spielen, um die Sie

  • Passen Sie die Schwelle mit einem Schieber
  • zu

    ermöglicht
  • Verwenden Sie die rechte Maustaste, um das Originalbild erneut zu sehen, überprüfen Sie die Grauwerte an verschiedenen Mauspositionen und klicken Sie auf die rechte Maustaste erneut, wechseln Sie zurück zur Schwellwertansicht und verwenden Sie den Grauwert der letzten Mausposition als neuen Schwellwert.

.

import cv2 
import numpy as np 

mode = "" 
Schwelle =0 

def nothing(x): 
    pass 

def read_pixel(event,x,y,flags,param): 
    global mode, Schwelle 
    if event == cv2.EVENT_MOUSEMOVE: 
     if mode == "Analyse": 
      ix,iy = x,y 
      font = cv2.FONT_HERSHEY_SIMPLEX 
      img2=img.copy() 
      cv2.putText(img2,str(ix)+" "+str(iy)+": "+str(img[y,x]),(50,50), font, 1,(255,255,255),2,cv2.LINE_AA)  
      cv2.imshow('image',img2) 
    elif event == cv2.EVENT_RBUTTONDOWN: 
     if mode == "Analyse": 
      mode="" 
      Schwelle=img[y,x] 
      cv2.createTrackbar('Schwelle','image',Schwelle,255,nothing)    
     else: 
      mode = "Analyse" 
    elif event == cv2.EVENT_LBUTTONDOWN: 
     Schwelle= img[y,x] 

img =cv2.imread('image.png',0) 
cv2.namedWindow('image') 
cv2.setMouseCallback('image',read_pixel) 
cv2.createTrackbar('Schwelle','image',128,255,nothing) 

while(1): 
    k = cv2.waitKey(1) & 0xFF 
    if k == 27: 
     break 

    if mode != "Analyse": 
     Schwelle = cv2.getTrackbarPos('Schwelle','image') 
     ret,thresh1 = cv2.threshold(img,Schwelle,255,cv2.THRESH_BINARY) 
     cv2.imshow('image',thresh1) 

cv2.destroyAllWindows() 
+0

Vielen Dank für die Bereitstellung dieser Lösung ... es ist hilfreich. Allerdings habe ich eine Frage zu den Details der Threading-Bilder: Obwohl das Thresholding das Bild an den Grenzen besser macht, macht es die innere Region leichter (die Region mit dunkelgrauer Farbe). Ist es möglich, ein Bild zu erhalten, das die interne Region von Bild # 2 und die Grenzregion von Bild # 3 (oder # 4) hat? – Pupil

+0

Ich muss zuerst einige Ihrer Einschränkungen und Absichten besser verstehen: 1.) Haben Sie mehr ähnliche Bilder zu inspizieren? Wenn ja, können Sie einige von ihnen zur Verfügung stellen? (Abdecken der Variation Aspekt) 2.) Was ist Ihr Endziel in Bezug auf Genauigkeit, möchten Sie zu visualisieren, möchten Sie Fläche zu messen, möchten Sie den Schwerpunkt finden ... – tfv

+0

Hallo ... in Bezug auf Ihr Kommentar: 1) Ich habe zwei Bilder zum Update-Abschnitt in der Frage hinzugefügt. 2) Mein Ziel ist es, die Anzahl der Pixel (Bruchteil der gesamten Bildfläche) zu berechnen, die von der dunkelgrauen Farbe eingenommen wird. – Pupil