RAW to Grayscale

Hello,
I am new to opencv here, can anyone help me here to convert RAW to Grayscale Image.
My camera (OV2311) outputs RAW data encapsulated in YUV2 format.

Kindly let me know if in case of more details required.

Thanks!

Could anyone help me to provide some information on how to convert RAW to Grayscale.
I tried using cvtColor(img, gray, COLOR_BGR2GRAY); the video captured from the camera with RGB color gets converted to Gray color, but I cannot see any Images captured.

‘RAW’ can be anything. what kind of camera is it ?

we cannot see your code, attempting this. can you show that, please ?

The camera is used from omnivision (ov2311), it outputs the RAW data encapsulated in YUY2 format.

here is the code:

int main()
{
auto cap = VideoCapture(0);

cap.set(CAP_PROP_FRAME_WIDTH, 1600);
cap.set(CAP_PROP_FRAME_HEIGHT, 1300);
cap.set(CAP_PROP_FPS, 30);

Mat img;

while (true)
{
	if (!cap.read(img))
		break;

	cap.read(img);
	imshow("RAW", img);

	Mat gray;
	cvtColor(img, gray, COLOR_YUV2BGR);
	cvtColor(img, gray, COLOR_BGR2GRAY);
	
	imshow("Gray", gray);

	waitKey(2);
}
return 0;

}

1 Like

that’s confusing. IF you can see the converted grayscale image, there must have been an image captured.

Yep, even I am confused why the image is not getting captured from the camera.

proof ? datasheet says:

output formats: 10-bit RAW

(which sounds more like 10bit monochrome to me)

please print out img.type(), img.size(), img.channels() , and show us

I have not observed this in the datasheet, but the camera supplier confirmed us.

size_channel_type

1 Like

The issue is that OpenCV itself already tries to convert whatever the camera produces, into BGR. You would have to disable that by setting CAP_PROP_CONVERT_RGB to 0

additionally, this code makes no sense:

I see images captured from the camera, verified by using the tool provided from the camera vendor, I have made the Exposure and Gain set to proper value by the register settings.
When I run my code and when I see the Images, its not so good in clarity.
Any suggestions what needs to be done in order to get the better clarity of the Image.

I also disable that by setting CAP_PROP_CONVERT_RGB to 0.

that looks like the depth is more than 8 bits.

is that latest picture the result of a conversion to grayscale? in what ways did you produce/alter that?

I have set the register setting values of exposure and gain to low i.e. exposure[15:8] - 0x02 and exposure[7:0] - 0x90 and gain to default value 0x01 to adjust the brightness in the tool provided from the camera vendor and confirmed the good quality Image.
Yes, The result of Image is the latest after the register settings and conversion to grayscale in openCV.

and why do you convert to grayscale?

Nice Question! The good quality image which I observed was in the vendor tool, which I cannot use it for the development purpose, the tool is just to verify it and make some register settings.
I need to use OpenCV for further development stuffs, hence I am trying to convert to grayscale.

convert after interpreting the data correctly. it looks like more than 8 bits, so what’s there (2-3 bytes per pixel?) needs to be reinterpreted first.

I can’t possibly talk you through undoing everything.

The tool has its own adaption of Raw to Grayscale conversion and hence can be seen good quality Image. The only option I see is take the recorded raw data from the tool and feed to the openCV.
I am trying to capture Raw camera image and try converting to grayscale in the openCV. As I tried to print the output of Type, it turned out to be 16-bit.

Hi,
I had the same issue as you.
I believe it is happening because V4L2 that creates the /dev/videoX interface does not support raw output. So the manufacturer has it described as YUVU when you run the command even though it is not a colour camera, its mono.

$v4l2-ctl --list-formats -d /dev/video2                                                                                                                            [16:09:49]
ioctl: VIDIOC_ENUM_FMT
	Type: Video Capture

	[0]: 'YUYV' (YUYV 4:2:2)

This means that if you use VideoLan, or AMCAP, or even OpenCV as-is, you get that strange green output above.

However, one solution is to manually configure OpenCV to read the pixels as native as possible, and then process them yourself. The following code worked for me:

# Description: This script is used to preview the video stream from the LI-OV2311 camera

import cv2
import numpy as np

# Check this using the terminal command "ls /dev/video*
cap = cv2.VideoCapture('/dev/video2')

# Set the resolution
width = 1600
height = 1300
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
cap.set(cv2.CAP_PROP_CONVERT_RGB, 0)  # Dont let opencv convert to RGB
# cap.set(cv2.CAP_PROP_FORMAT, -1)

# Set the frame rate
fps = 2
cap.set(cv2.CAP_PROP_FPS, fps)

while True:
    ret, frame = cap.read()
    # print(f"frame shape: {frame.shape}")

    # Frame has the shape of (1300, 1600, 2) and is a mono image
    # There are 10 bits per pixel. These are padded in the two bytes

    if frame is None:
        print("frame is None")
        break

    frame_16 = frame.view(dtype=np.int16)       # reinterpret data as 16-bit pixels
    frame_sh = np.right_shift(frame_16, 2)      # Shift away the bottom 2 bits
    frame_8  = frame_sh.astype(np.uint8)        # Keep the top 8 bits       

    if not ret:
        print("ret is False")
        break

    cv2.imshow('img', frame_8)

    if cv2.waitKey(1) == ord('q'):
        cap.release()
        cv2.destroyAllWindows()
        break

cap.release()
cv2.destroyAllWindows()

Sample output image below: