How do you convert a grayscale OpenCV image to black and white? I see a similar question has already been asked, but I'm using OpenCV 2.3, and the proposed solution no longer seems to work.
I'm trying to convert a greyscale image to black and white, so that anything not absolutely black is white, and use this as a mask for surf.detect(), in order to ignore keypoints found on the edge of the black mask area.
The following Python gets me almost there, but the threshold value sent to Threshold() doesn't appear to have any effect. If I set it to 0 or 16 or 128 or 255, the result is the same, with all pixels with a value > 128 becoming white, and everything else becoming black.
What am I doing wrong?
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()
Step 1: Import OpenCV. Step 2: Read the original image using imread(). Step 3: Convert to grayscale using cv2. cvtcolor() function.
Convert an Image to Grayscale in Python Using the Conversion Formula and the Matplotlib Library. We can also convert an image to grayscale using the standard RGB to grayscale conversion formula that is imgGray = 0.2989 * R + 0.5870 * G + 0.1140 * B .
If you want to save a color image (3D ndarray ) as a grayscale image file, convert it to grayscale with cv2. cvtColor() and cv2. COLOR_BGR2GRAY . If you save 2D ndarray to a file and read it again with cv2.
Importance of grayscaling. Dimension reduction: For example, In RGB images there are three color channels and has three dimensions while grayscale images are single-dimensional. Reduces model complexity: Consider training neural article on RGB images of 10x10x3 pixel. The input layer will have 300 input nodes.
Step-by-step answer similar to the one you refer to, using the new cv2 Python bindings:
1. Read a grayscale image
import cv2 im_gray = cv2.imread('grayscale_image.png', cv2.IMREAD_GRAYSCALE)
2. Convert grayscale image to binary
(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
which determines the threshold automatically from the image using Otsu's method, or if you already know the threshold you can use:
thresh = 127 im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
3. Save to disk
cv2.imwrite('bw_image.png', im_bw)
Specifying CV_THRESH_OTSU
causes the threshold value to be ignored. From the documentation:
Also, the special value THRESH_OTSU may be combined with one of the above values. In this case, the function determines the optimal threshold value using the Otsu’s algorithm and uses it instead of the specified thresh . The function returns the computed threshold value. Currently, the Otsu’s method is implemented only for 8-bit images.
This code reads frames from the camera and performs the binary threshold at the value 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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With