I have a custom USB camera, which sending 16 bit/pixel 400x400pixel image. I try to make a visible version of the image. I already found a python script which(with minimal modification) is able to show the proper image in grayscale. When i try to recrate the code in c++(for experimenting with the recoloring), After i grab the image check the channels and elem number, I try to read the image as a 2 byte/pixel image for that a read it as a 400x400x2 8bitimage. But I always got the message that the “raw” frame also 400*400pixel.
I currently using this code snippet for grabbing:
I am new to OpenCV and the pixel formats, but I want to learn how to handle them. I read multiple post about the topic, but now I am a bit confused. I would be really greatful any kind of help.
Hi! Thanks for the response. Currently i experimenting under windows, and with the DSHOW Api backend. yes you are right preallocating has no effect. Code input:
The only modification was the bit shifting increased from 3 to 6. And added image saving and text saving lines for understanding what happening. Also tried to recreate the colors at the end of the script, but not much luck.
cap = cv2.VideoCapture(1, cv2.CAP_MSMF)
# set width and height
cols, rows = 400, 400,
cap.set(cv2.CAP_PROP_FRAME_WIDTH, cols)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, rows)
cap.set(cv2.CAP_PROP_FPS, 30)
cap.set(cv2.CAP_PROP_CONVERT_RGB, 0)
# Fetch undecoded RAW video streams
cap.set(cv2.CAP_PROP_FORMAT, -1) # Format of the Mat objects. Set value -1 to fetch
undecoded RAW video streams (as Mat 8UC1)
while True:
# Capture frame-by-frame
ret, frame = cap.read()#read into np array with [1,320000] h*w*2 byte
#print(frame.shape)
if not ret:
break
# Convert the frame from uint8 elements to big-endian signed int16 format.
frame = frame.reshape(rows, cols*2) # Reshape to 800*400
#cv2.imwrite('framereshaped.png', frame)
frame = frame.astype(np.uint16) # Convert uint8 elements to uint16 elements
#cv2.imwrite('framecasted.png', frame)
np.savetxt('test.txt', frame, fmt="%d")
frame = (frame[:, 0::2] << 8) + frame[:, 1::2] # Convert from little endian to big endian (apply byte swap), the result is 340x240.
#cv2.imwrite('framebigendian.png', frame)
np.savetxt('testendian.txt', frame, fmt="%d")
frame = frame.view(np.int16)
np.savetxt('testint16.txt', frame, fmt="%d")
#cv2.imwrite('frameview16.png', frame)
# Apply some processing for disapply (this part is just "cosmetics"):
frame_roi = frame[:, 10:-10] # Crop 320x240 (the left and right parts are not meant to be displayed).
# frame_roi = cv2.medianBlur(frame_roi, 3) # Clean the dead pixels (just for better viewing the image).
frame_roi = frame_roi << 6 # shift the 6 most left bits
#cv2.imwrite('frameshifted.png', frame_roi)
normed = cv2.normalize(frame_roi, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC3) # Convert to uint8 with normalizing (just for viewing the image).
#cv2.imwrite('framenormed.png', normed)
gray = cv2.cvtColor(normed, cv2.COLOR_BAYER_RG2RGB)