如何使用opencv处理原始10位视频信号,以避免图像紫色失真?

发布于 2025-01-14 15:13:04 字数 4697 浏览 8 评论 0 原文

我创建了一个定制的 UVC 相机,它可以传输 10 位原始 RGB(数据表所述)传感器的图像。但我必须将 10 位信号打包成 16 位数据包,并将描述符写入 YUY2 媒体(UVC 不支持原始格式)。现在我有视频源(用 amcap、vlc、自定义 opencv 应用程序打开它)。视频有噪音且呈紫色。我开始使用 openCV 处理数据并阅读了一堆有关该问题的帖子,但现在我有点困惑如何解决该问题。我很想了解有关图像格式和处理的更多信息,但现在信息量有点过多,需要一些指导。同样基于传感器数据表,它是 BGGR 拜耳网格,类似的帖子将问题描述为绿色噪声图片,但我有紫色图片。

来自相机的紫色图像

来自相机的紫色图像

更新: 我使用提到的帖子帖子来获得正确的16位一通道图像(灰度),但我无法正确对图像进行去马赛克。

import cv2
import numpy as np
# open video0
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
    frame = frame.astype(np.uint16) # Convert uint8 elements to uint16 elements
    frame = (frame[:, 0::2] << 8) + frame[:, 1::2]  # Convert from little endian to big endian (apply byte swap), the result is 340x240.
    frame = frame.view(np.int16)

    # 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
    normed = cv2.normalize(frame_roi, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC3)  # Convert to uint8 with normalizing (just for viewing the image).
    gray = cv2.cvtColor(normed, cv2.COLOR_BAYER_GR2BGR)
    cv2.imshow('normed', normed)  # Show the normalized video frame
    cv2.imshow('rgb', gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    cv2.imwrite('normed.png', normed)
    cv2.imwrite('colored.png', gray)

cap.release()
cv2.destroyAllWindows()

从此:

我得到了这个:

在此处输入图像描述

第二次更新:

为了获取有关图像状态的更多相关信息,我用不同的目标拍摄了一些照片(另一个带有相机模块的开发板,两者都应该为蓝色,PCB 应为橙色),我用相机的测试图案重复了这一点。我在脚本的每一步后都拍了照片: frame.reshape(row, cols*2) 相机目标 frame. reshape(row, cols*2)

frame.reshape(row, cols*2) 测试模式 frame. reshape(row, cols*2)tp

frame.astype(np.uint16) 相机目标 输入图片此处描述

frame.astype(np.uint16) 测试模式 输入图片此处描述

frame.view(np.int16) 相机目标 输入图片此处描述

frame.view(np.int16) 测试模式 输入图片此处描述

cv2.normalize 相机目标 输入图片此处描述

cv2.normalize 测试模式 输入图片此处描述

cv2.COLOR_BAYER_GR2BGR 相机目标 输入图片此处描述

cv2.COLOR_BAYER_GR2BGR 测试图案 输入图片此处描述

在相机目标图片的底部和顶部有一个粉红色的包裹箔,用于保护相机(图片上看起来是绿色的)。供应商没有向我提供传感器的文档,所以我不知道正确的测试模式应该是什么样子,但我确信那是不正确的。

I have created a custom UVC camera, which can streaming a 10 bit raw RGB(datasheet said) sensor's image. But i had to pack the 10 bit signal into 16 bit packets, and write the descriptors as a YUY2 media(UVC not support raw format). Now I have video feed(opened it witm amcap,vlc, custom opencv app). The video is noisy and purple. I started to process the data with openCV and read bunch of posts about the problem, but now I am bit confused how to solve the problem. I would love to learn more about the image formats and processing, but now a bit overhelmed the amount of information and need some guidance. Also based on the sensor datasheet it is a BGGR bayer grid, and the similar posts describe the problem as a greenish noisy picture, but i have purple pictures.

purple image from the camera

purple image from the camera

UPDATE:
I used the mentioned post post for get proper 16 bit one channel image (gray scale), but I am not able to demosaicing the image properly.

import cv2
import numpy as np
# open video0
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
    frame = frame.astype(np.uint16) # Convert uint8 elements to uint16 elements
    frame = (frame[:, 0::2] << 8) + frame[:, 1::2]  # Convert from little endian to big endian (apply byte swap), the result is 340x240.
    frame = frame.view(np.int16)

    # 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
    normed = cv2.normalize(frame_roi, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC3)  # Convert to uint8 with normalizing (just for viewing the image).
    gray = cv2.cvtColor(normed, cv2.COLOR_BAYER_GR2BGR)
    cv2.imshow('normed', normed)  # Show the normalized video frame
    cv2.imshow('rgb', gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    cv2.imwrite('normed.png', normed)
    cv2.imwrite('colored.png', gray)

cap.release()
cv2.destroyAllWindows()

from this:

enter image description here

i got this:

enter image description here

SECOND UPDATE:

To get more relevant informations about the image status I took some pictures with a different target(another devboard with a camera module, both of the should be blue and the PCB shoulb be orangeish), I repeated this with the test pattern of the camera. I took pictures after every step of the script:
frame.reshaped(row, cols*2) camera target
frame.reshaped(row, cols*2)

frame.reshaped(row, cols*2) test pattern
frame.reshaped(row, cols*2)tp

frame.astype(np.uint16) camera target
enter image description here

frame.astype(np.uint16) test pattern
enter image description here

frame.view(np.int16) camera target
enter image description here

frame.view(np.int16) test pattern
enter image description here

cv2.normalize camera target
enter image description here

cv2.normalize test pattern
enter image description here

cv2.COLOR_BAYER_GR2BGR camera target
enter image description here

cv2.COLOR_BAYER_GR2BGR test pattern
enter image description here

On the bottom and top of the camera target pictures there a pink wrap foil for protect the camera(looks green on the picture). The vendor did not provide me the documentation of the sensor, so i do not know how should look like the proper test pattern, but I am sure that one not correct.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文