it-swarm.com.de

Konvertieren eines OpenCV-Bildes in Schwarzweiß

Wie konvertiert man ein Graustufen-OpenCV-Bild in Schwarzweiß? Ich sehe eine ähnliche Frage wurde bereits gefragt, aber ich verwende OpenCV 2.3, und die vorgeschlagene Lösung scheint nicht mehr zu funktionieren.

Ich versuche, ein Graustufenbild in Schwarzweiß zu konvertieren, sodass alles, was nicht absolut Schwarz ist, weiß ist, und verwende diese als Maske für surf.detect () , um die am Edge von gefundenen Schlüsselpunkte zu ignorieren der schwarze Maskenbereich.

Der folgende Python bringt mich fast dorthin, aber der an Threshold () gesendete Schwellenwert scheint keine Wirkung zu haben. Wenn ich sie auf 0 oder 16 oder 128 oder 255 stelle, ist das Ergebnis dasselbe, wobei alle Pixel mit einem Wert> 128 weiß werden und alles andere schwarz wird.

Was mache ich falsch?

import cv, cv2
fn = 'myfile.jpg'
im_gray = cv2.imread(fn, cv.CV_LOAD_IMAGE_GRAYSCALE)
im_gray_mat = cv.fromarray(im_gray)
im_bw = cv.CreateImage(cv.GetSize(im_gray_mat), cv.IPL_DEPTH_8U, 1);
im_bw_mat = cv.GetMat(im_bw)
threshold = 0 # 128#255# HAS NO EFFECT!?!?
cv.Threshold(im_gray_mat, im_bw_mat, threshold, 255, cv.CV_THRESH_BINARY | cv.CV_THRESH_OTSU);
cv2.imshow('', np.asarray(im_bw_mat))
cv2.waitKey()
37
Cerin

Eine schrittweise Antwort ähnlich der, auf die Sie sich beziehen, unter Verwendung der neuen cv2-Python-Bindungen:

1. Lesen Sie ein Graustufenbild

import cv2
im_gray = cv2.imread('grayscale_image.png', cv2.IMREAD_GRAYSCALE)

2. Graustufenbild in Binärformat konvertieren

(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

die den Schwellenwert automatisch mithilfe des Otsu-Verfahrens aus dem Bild bestimmt, oder wenn Sie den Schwellenwert bereits kennen, können Sie Folgendes verwenden:

thresh = 127
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]

3. Speichern auf Festplatte

cv2.imwrite('bw_image.png', im_bw)
79
tsh

Durch die Angabe von CV_THRESH_OTSU wird der Schwellenwert ignoriert. Aus der Dokumentation

Der spezielle Wert THRESH_OTSU kann auch mit einem der obigen Werte kombiniert werden. In diesem Fall ermittelt die Funktion den optimalen Schwellenwert mithilfe des Otsu-Algorithmus und verwendet diesen anstelle des angegebenen Schwellenwerts. Die Funktion gibt den berechneten Schwellenwert zurück. Derzeit ist die Otsu-Methode nur für 8-Bit-Bilder implementiert.

Dieser Code liest Bilder von der Kamera und führt den binären Schwellenwert mit dem Wert 20 aus.

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

int main(int argc, const char * argv[]) {

    VideoCapture cap; 
    if(argc > 1) 
        cap.open(string(argv[1])); 
    else 
        cap.open(0); 
    Mat frame; 
    namedWindow("video", 1); 
    for(;;) {
        cap >> frame; 
        if(!frame.data) 
            break; 
        cvtColor(frame, frame, CV_BGR2GRAY);
        threshold(frame, frame, 20, 255, THRESH_BINARY);
        imshow("video", frame); 
        if(waitKey(30) >= 0) 
            break;
    }

    return 0;
}
8
SSteve

Ansatz 1

Beim Konvertieren eines Graustufenbilds in ein Binärbild verwenden wir normalerweise cv2.threshold() und stellen manuell einen Schwellenwert ein. Manchmal entscheiden wir uns für Otsus Binarisierung , um ein anständiges Ergebnis zu erzielen.

Ich habe einen kleinen Hack, den ich beim Lesen einiger Blog-Posts gesehen habe.

  1. Konvertieren Sie Ihr Farbbild (RGB) in Graustufen.
  2. Ermitteln Sie den Median des Graustufenbilds.
  3. Wählen Sie einen Schwellenwert, der entweder 33% über dem Median liegt

enter image description here

Warum 33%?

Dies liegt daran, dass 33% für die meisten Bilder/Datensätze geeignet sind.

Sie können den gleichen Ansatz auch ausführen, indem Sie median durch mean ersetzen.

Ansatz 2

Ein anderer Ansatz wäre, eine x Anzahl von Standardabweichungen (std) vom Mittelwert zu nehmen, entweder auf der positiven oder der negativen Seite; und legen Sie einen Schwellenwert fest. Es könnte also eine der folgenden sein:

  • th1 = mean - (x * std)
  • th2 = mean + (x * std)

Hinweis: Vor dem Anwenden des Schwellenwerts ist es ratsam, den Kontrast des Graustufenbilds zu verbessern lokal (Siehe CLAHE ).

5
Jeru Luke

Sie können einfach das folgende Code-Snippet schreiben, um ein OpenCV-Bild in ein Graustufenbild zu konvertieren

import cv2
image = cv2.imread('image.jpg',0)
cv2.imshow('grey scale image',image)

Beachten Sie, dass image.jpg und der Code im selben Ordner gespeichert werden müssen. 

Beachten Sie, dass:

  • ('image.jpg') ergibt ein RGB-Bild
  • ('image.jpg',0) ergibt ein Graustufenbild.
5
Ananth Reddy

Wenn Sie cv.CV_THRESH_BINARY verwenden, bedeutet dies, dass jedes Pixel, das größer als der Schwellenwert ist, zum Maximalwert wird (in Ihrem Fall 255). Andernfalls ist der Wert 0. Wenn der Schwellenwert 0 ist, wird alles weiß (Maximalwert = 255), und wenn Wert ist 255, alles wird schwarz (dh 0).

Wenn Sie keinen Schwellenwert ermitteln möchten, können Sie die Otsu-Methode verwenden. Bei der Implementierung von OpenCV funktioniert dieser Algorithmus jedoch nur mit 8-Bit-Bildern. Wenn es sich bei Ihrem Bild um ein 8-Bit-Bild handelt, verwenden Sie den folgenden Algorithmus:

cv.Threshold(im_gray_mat, im_bw_mat, threshold, 255, cv.CV_THRESH_BINARY | cv.CV_THRESH_OTSU);

Egal wie hoch der Schwellenwert ist, wenn Sie ein 8-Bit-Bild haben.

1
javier

Hier ist ein zweizeiliger Code, den ich online gefunden habe und der für Anfänger hilfreich sein könnte

# Absolute value of the 32/64
abs_image_in32_64 = np.absolute(image_in32_64)

image_8U = np.uint8(abs_image_in32_64)
1
Santhosh

Für diejenigen, die ein Video machen, habe ich Folgendes basierend auf @tsh gepflastert:

import cv2 as cv
import numpy as np

def nothing(x):pass

cap = cv.VideoCapture(0)
cv.namedWindow('videoUI', cv.WINDOW_NORMAL)
cv.createTrackbar('T','videoUI',0,255,nothing)

while(True):
    ret, frame = cap.read()
    vid_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    thresh = cv.getTrackbarPos('T','videoUI');
    vid_bw = cv.threshold(vid_gray, thresh, 255, cv.THRESH_BINARY)[1]

    cv.imshow('videoUI',cv.flip(vid_bw,1))

    if cv.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv.destroyAllWindows()

Ergebnisse in:

 enter image description here

0
Keno