By mohammed

2009-10-18 17:41:40 8 Comments

I would like to know how to convert an RGB image into a black & white (binary) image.

After conversion, how can I save the modified image to disk?


@MD. Nazmul Kibria 2016-10-21 13:05:32

Simple binary threshold method is sufficient.


#include <string>
#include "opencv/highgui.h"
#include "opencv2/imgproc/imgproc.hpp"

using namespace std;
using namespace cv;

int main()
    Mat img = imread("./img.jpg",0);//loading gray scale image
    threshold(img, img, 128, 255, CV_THRESH_BINARY);//threshold binary, you can change threshold 128 to your convenient threshold
    return 0;

You can use GaussianBlur to get a smooth black and white image.

@nikithashr 2015-10-06 08:28:41

This seemed to have worked for me!

Mat a_image = imread(argv[1]);

cvtColor(a_image, a_image, CV_BGR2GRAY);
GaussianBlur(a_image, a_image, Size(7,7), 1.5, 1.5);
threshold(a_image, a_image, 100, 255, CV_THRESH_BINARY);

@Rehb 2015-09-01 11:14:19

Use cv2 and Python:

1- Grayscale Image

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

2- Convert image to Binary

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

3- Store to Disck

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

@kevto 2016-10-21 12:56:48

This applies the threshold indeed but the bitdepth remains 8.

@alvaropgl 2014-05-05 21:57:57

A simple way of "binarize" an image is to compare to a threshold: For example you can compare all elements in a matrix against a value with opencv in c++

cv::Mat img = cv::imread("image.jpg", CV_LOAD_IMAGE_GRAYSCALE); 
cv::Mat bw = img > 128;

In this way, all pixels in the matrix greater than 128 now are white, and these less than 128 or equals will be black

Optionally, and for me gave good results is to apply blur

cv::blur( bw, bw, cv::Size(3,3) );

Later you can save it as said before with:

cv::imwrite("image_bw.jpg", bw);

@user1741137 2015-05-05 18:35:08

Is JPEG really the right format for B&W????

@alvaropgl 2015-05-11 14:26:26

I don't know... I think its depends in what type of image are you saving. For photographs (i was working with photos) I think is the right format.

@user1741137 2015-05-11 18:21:31

Well, the problem with JPEG is that it introduces artefacts and degrades the quality of your picture somewhat. I would use PNG or for really small files TIFF with CCITT Fax 4 compression.

@Alexander Abakumov 2015-06-17 11:24:26

@user1741137, How to save a Mat as a TIFF with CCITT Fax 4 compression with OpenCV? Using Highgui.imwrite("sample.tiff", binaryImage); I always get a TIFF with LZW compression and 8-bit color depth - see my question here.

@Jacob 2009-10-18 23:42:57

AFAIK, you have to convert it to grayscale and then threshold it to binary.

1. Read the image as a grayscale image If you're reading the RGB image from disk, then you can directly read it as a grayscale image, like this:

// C
IplImage* im_gray = cvLoadImage("image.jpg",CV_LOAD_IMAGE_GRAYSCALE);

// C++ (OpenCV 2.0)
Mat im_gray = imread("image.jpg",CV_LOAD_IMAGE_GRAYSCALE);

2. Convert an RGB image im_rgb into a grayscale image: Otherwise, you'll have to convert the previously obtained RGB image into a grayscale image

// C
IplImage *im_rgb  = cvLoadImage("image.jpg");
IplImage *im_gray = cvCreateImage(cvGetSize(im_rgb),IPL_DEPTH_8U,1);

// C++
Mat im_rgb  = imread("image.jpg");
Mat im_gray;

3. Convert to binary You can use adaptive thresholding or fixed-level thresholding to convert your grayscale image to a binary image.

E.g. in C you can do the following (you can also do the same in C++ with Mat and the corresponding functions):

// C
IplImage* im_bw = cvCreateImage(cvGetSize(im_gray),IPL_DEPTH_8U,1);
cvThreshold(im_gray, im_bw, 128, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

// C++
Mat img_bw = im_gray > 128;

In the above example, 128 is the threshold.

4. Save to disk

// C

// C++
imwrite("image_bw.jpg", img_bw);

@Mark Ransom 2012-09-11 16:45:16

Depending on the application you may want to do a dithering rather than a simple threshold.

@evk1206 2016-02-09 12:35:29

in CvtColor function do we need to use CV_RGB2GRAY or CV_BGR2GRAY. I have read that opencv is based on BGR format and we need to use that , but in the gray or binary image I am not seeing any differences when using either of them

@AndyUK 2011-08-13 15:37:51

I do something similar in one of my blog postings. A simple C++ example is shown.

The aim was to use the open source cvBlobsLib library for the detection of spot samples printed to microarray slides, but the images have to be converted from colour -> grayscale -> black + white as you mentioned, in order to achieve this.

@RidaSana 2011-10-30 14:54:15

I would like to see your this work : the images have to be converted from colour -> grayscale -> black + white as you mentioned, Thanks

@Yeraze 2012-08-20 18:42:12

The link mentioned above doens't work, this one does : link

Related Questions

Sponsored Content

35 Answered Questions

3 Answered Questions

[SOLVED] Simple Digit Recognition OCR in OpenCV-Python

7 Answered Questions

[SOLVED] Converting an OpenCV Image to Black and White

23 Answered Questions

[SOLVED] Image Processing: Algorithm Improvement for 'Coca-Cola Can' Recognition

6 Answered Questions

[SOLVED] Convert RGB to black OR white

10 Answered Questions

9 Answered Questions

[SOLVED] Improve INSERT-per-second performance of SQLite?

2 Answered Questions

[SOLVED] Convert White Pixels to Black in OpenCV python

  • 2018-07-15 09:45:19
  • Gaurav Sawant
  • 1539 View
  • 0 Score
  • 2 Answer
  • Tags:   python opencv

2 Answered Questions

[SOLVED] opencv convert black and white to green and blue

  • 2011-08-30 09:12:41
  • Developer
  • 2338 View
  • 0 Score
  • 2 Answer
  • Tags:   opencv

1 Answered Questions

[SOLVED] converting RGB to YCbCr in OpenCV

  • 2015-04-17 01:12:40
  • user3805574
  • 4689 View
  • 0 Score
  • 1 Answer
  • Tags:   opencv

Sponsored Content