Comment convertir une image OpenCV en niveaux de gris en noir et blanc? Je vois une une question similaire a déjà été posée, mais j'utilise OpenCV 2.3 et la solution proposée ne semble plus fonctionner.
J'essaie de convertir une image en niveaux de gris en noir et blanc, de sorte que tout ce qui n'est pas absolument noir soit en blanc, et l'utiliser comme masque pour surf.detect () , afin d'ignorer les points clés situés sur le bord la zone de masque noir.
Le code Python suivant me le permet presque, mais la valeur de seuil envoyée à Threshold () ne semble pas avoir d’effet. Si je le règle sur 0 ou 16 ou 128 ou 255, le résultat est le même: tous les pixels dont la valeur est supérieure à 128 deviennent blancs et tout le reste devient noir.
Qu'est-ce que je fais mal?
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()
Répondez étape par étape de manière similaire à celle à laquelle vous vous référez, à l'aide des nouvelles liaisons cv2 Python
1. Lire une image en niveaux de gris
import cv2
im_gray = cv2.imread('grayscale_image.png', cv2.IMREAD_GRAYSCALE)
2. Convertir une image en niveaux de gris en binaire
(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
qui détermine le seuil automatiquement à partir de l'image en utilisant la méthode d'Otsu, ou si vous connaissez déjà le seuil, vous pouvez utiliser:
thresh = 127
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
3. Enregistrer sur le disque
cv2.imwrite('bw_image.png', im_bw)
Si vous spécifiez CV_THRESH_OTSU
, la valeur de seuil est ignorée. De la documentation :
De plus, la valeur spéciale THRESH_OTSU peut être combinée avec l'une des valeurs ci-dessus. Dans ce cas, la fonction détermine la valeur de seuil optimale en utilisant l’algorithme d’Otsu et l’utilise à la place du seuil spécifié. La fonction renvoie la valeur de seuil calculée. Actuellement, la méthode Otsu n’est implémentée que pour les images 8 bits.
Ce code lit les images de la caméra et exécute le seuil binaire à la valeur 20.
#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;
}
Vous pouvez simplement écrire l'extrait de code suivant pour convertir une image OpenCV en une image en niveaux de gris
import cv2
image = cv2.imread('image.jpg',0)
cv2.imshow('grey scale image',image)
Notez que le fichier image.jpg et le code doivent être enregistrés dans le même dossier.
Notez que:
('image.jpg')
donne une image RVB('image.jpg',0)
donne une image en niveaux de gris.Voici un code de deux lignes que j'ai trouvé en ligne qui pourrait être utile pour un débutant
# Absolute value of the 32/64
abs_image_in32_64 = np.absolute(image_in32_64)
image_8U = np.uint8(abs_image_in32_64)
Pour ceux qui font de la vidéo, j'ai bricolé ce qui suit d'après @tsh:
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()
Résulte en: