Opencv - Grayscale mode Vs gray color convertion
Question: I am working in opencv(2.4.11) python(2.7) and was playing around with gray
images. I found an unusual behavior when loading image in gray scale mode and
converting image from BGR to GRAY. Following is my experimental code:

    
    
    import cv2
    
    path = 'some/path/to/color/image.jpg'
    
    # Load color image (BGR) and convert to gray
    img = cv2.imread(path)
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # Load in grayscale mode
    img_gray_mode = cv2.imread(path, 0)
    
    # diff = img_gray_mode - img_gray
    diff = cv2.bitwise_xor(img_gray,img_gray_mode)
    
    cv2.imshow('diff', diff)
    cv2.waitKey()
    

When I viewed the difference image, I can see the left out pixels instead of
jet black image. Can you suggest any reason? What is the correct way of
working with gray images.  
  
_P.S. When I use both the images in SIFT, keypoints are different which may
lead to different outcome specially when working with bad quality images._


Answer: **Note: This is not a duplicate** , because the OP is aware that the image
from `cv2.imread` is in BGR format (unlike the suggested duplicate question
that assumed it was RGB hence the provided answers only address that issue)

To illustrate, I've opened up this same color JPEG image:

[![enter image description
here](http://i.stack.imgur.com/mzjlI.png)](http://i.stack.imgur.com/mzjlI.png)

once using the conversion

    
    
    img = cv2.imread(path)
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    

and another by loading it in gray scale mode

    
    
    img_gray_mode = cv2.imread(path, vs2.IMREAD_GRAYSCALE)
    

Like you've documented, the diff between the two images is not perfectly 0, I
can see diff pixels in towards the left and the bottom

[![enter image description
here](http://i.stack.imgur.com/d1uh1.png)](http://i.stack.imgur.com/d1uh1.png)

I've summed up the diff too to see

    
    
    import numpy as np
    np.sum(diff)
    # I got 6143, on a 494 x 750 image
    

**I tried all`cv2.imread()` modes**

Among all the `IMREAD_` modes for `cv2.imread()`, only `IMREAD_COLOR` and
`IMREAD_ANYCOLOR` can be converted using `COLOR_BGR2GRAY`, and both of them
gave me the same diff against the image opened in `IMREAD_GRAYSCALE`

The difference doesn't seem that big. My guess is comes from the differences
in the numeric calculations in the two methods (loading grayscale vs
conversion to grayscale)

Naturally what you want to avoid is fine tuning your code on a particular
version of the image just to find out it was suboptimal for images coming from
a different source.

**In brief, let's not mix the versions and types in the processing pipeline.**

So I'd keep the image sources homogenous, e.g. if you have capturing the image
from a video camera in BGR, then I'd use BGR as the source, and do the BGR to
grayscale conversion `cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)`

Vice versa if my ultimate source is grayscale then I'd open the files and the
video capture in gray scale `cv2.imread(path, cv2.IMREAD_GRAYSCALE)`

