Python 从Ubuntu中的RCCC拜耳摄像头传感器读取图像流

Python 从Ubuntu中的RCCC拜耳摄像头传感器读取图像流,python,image,opencv,video-streaming,Python,Image,Opencv,Video Streaming,我使用的是LI-AR0820 GMSL2相机,它使用半AR0820传感器,以12位RCCC拜耳格式捕获图像。我想从相机中读取实时图像流,并将其转换为灰度图像(使用去马赛克算法),然后将其输入到目标检测算法中。但是,由于OpenCV不支持RCCC格式,我无法使用VideoCapture类从相机获取图像数据。我正在寻找类似的东西,以获得类似数组格式的流图像数据,以便进一步操作它。有什么想法吗 我正在用OpenCV 3.2.0和Python 3.7.1运行Ubuntu18.04 编辑。我正在使用代码

我使用的是LI-AR0820 GMSL2相机,它使用半AR0820传感器,以12位RCCC拜耳格式捕获图像。我想从相机中读取实时图像流,并将其转换为灰度图像(使用去马赛克算法),然后将其输入到目标检测算法中。但是,由于OpenCV不支持RCCC格式,我无法使用VideoCapture类从相机获取图像数据。我正在寻找类似的东西,以获得类似数组格式的流图像数据,以便进一步操作它。有什么想法吗

我正在用OpenCV 3.2.0和Python 3.7.1运行Ubuntu18.04

编辑。我正在使用代码

#包括
#包括
#包括
#包括
#包括
int main(){
//每个像素由16位组成,高4位始终等于0
无符号字符字节[2];
//将数据保存在向量中
std::矢量数据;
//读取相机数据
FILE*fp=fopen(“test.raw”、“rb”);
while(fread(字节,2,1,fp)!=0){
//数据以小尾数形式出现,因此将第二个字节右移并连接第一个字节

数据。如果您的相机支持
CAP\u PROP\u CONVERT\u RGB
属性,您可能可以从VideoCapture获取原始RCCC数据。通过将此属性设置为
False
,您可以禁用到RGB的转换。因此,您可以使用以下代码捕获原始帧(为简单起见,无需进行错误检查):

我不知道这对你的相机是否有用

如果您能够以某种方式获得原始图像,则可以应用模拟设备appnote中描述的去镶嵌方法

带最优滤波器

我按照appnote中的描述编写了以下python代码,以测试RCCC->GRAY转换

import cv2
import numpy as np

rgb = cv2.cvtColor(cv2.imread('RGB.png'), cv2.COLOR_BGR2RGB)
c = cv2.cvtColor(rgb, cv2.COLOR_RGB2GRAY)
r = rgb[:, :, 0]

# no error checking. c shape must be a multiple of 2
rmask = np.tile([[1, 0], [0, 0]], [c.shape[0]//2, c.shape[1]//2])
cmask = np.tile([[0, 1], [1, 1]], [c.shape[0]//2, c.shape[1]//2])

# create RCCC image  by replacing 1 pixel out of 2x2 pixel region 
# in the monochrome image (c) with a red pixel
rccc = (rmask*r + cmask*c).astype(np.uint8)

# RCCC -> GRAY conversion
def rccc_demosaic(rccc, rmask, cmask, filt):
    # RCCC -> GRAY
    # use border type REFLECT_101 to give correct results for border pixels
    filtered = cv2.filter2D(src=rccc, ddepth=-1, kernel=filt, 
                         anchor=(-1, -1), borderType=cv2.BORDER_REFLECT_101)

    demos = (rmask*filtered + cmask*rccc).astype(np.uint8)

    return demos

# demo of the optimal filter
zeta = 0.5
kernel_4neighbor = np.array([[0, 0, 0, 0, 0], 
                             [0, 0, 1, 0, 0], 
                             [0, 1, 0, 1, 0], 
                             [0, 0, 1, 0, 0], 
                             [0, 0, 0, 0, 0]])/4.0
kernel_optimal   = np.array([[0, 0, -1, 0, 0], 
                             [0, 0, 2, 0, 0], 
                             [-1, 2, 4, 2, -1], 
                             [0, 0, 2, 0, 0], 
                             [0, 0, -1, 0, 0]])/8.0
kernel_param     = np.array([[0, 0, -1./4, 0, 0], 
                             [0, 0, 0, 0, 0], 
                             [-1./4, 0, 1., 0, -1./4], 
                             [0, 0, 0, 0, 0], 
                             [0, 0, -1./4, 0, 0]])

# apply optimal filter (Figure 7)
opt1 = rccc_demosaic(rccc, rmask, cmask, kernel_optimal)
# parametric filter with zeta = 0.5 (Figure 5)
opt2 = rccc_demosaic(rccc, rmask, cmask, kernel_4neighbor + zeta * kernel_param)

# PSNR
print(10 * np.log10(255**2/((c - opt1)**2).mean()))
print(10 * np.log10(255**2/((c - opt2)**2).mean()))
输入RGB:

模拟RCCC图像:

去镶嵌算法生成的灰度图像:

还有一件事:


如果您的相机供应商提供了适用于Linux的SDK,它可能有一个API来执行RCCC->灰度转换,或者至少获取原始图像。如果SDK中没有RCCC->灰度转换,C#示例代码中应该有它,因此我建议您查看一下他们的代码。

请提供一些代码,说明您当前如何从传感器读取图像。如果您有一个字节流(编码或原始)您可以将其转换为opencv mat。如果您的相机支持,您将能够读取数据。相机是否通过USB 3.0连接到您的机器?根据相机的数据表,它符合UVC。因此,原则上,VideoCapture应该可以工作。您可以分享VideoCapture失败的更多细节吗?VideoCapture读取一个奇怪的绿色image,就像在第一页左下角找到的一样:感谢您提供的解决方案!我会尽快测试它。供应商确实提供了SDK,但它仅适用于Windows,并且输出图像是镶嵌的(如上面的第二个图像)。
cap = cv2.VideoCapture(0)
# disable converting images to RGB
cap.set(cv2.CAP_PROP_CONVERT_RGB, False)
while(True):
    ret, frame = cap.read()
    # other processing ...
cap.release()
import cv2
import numpy as np

rgb = cv2.cvtColor(cv2.imread('RGB.png'), cv2.COLOR_BGR2RGB)
c = cv2.cvtColor(rgb, cv2.COLOR_RGB2GRAY)
r = rgb[:, :, 0]

# no error checking. c shape must be a multiple of 2
rmask = np.tile([[1, 0], [0, 0]], [c.shape[0]//2, c.shape[1]//2])
cmask = np.tile([[0, 1], [1, 1]], [c.shape[0]//2, c.shape[1]//2])

# create RCCC image  by replacing 1 pixel out of 2x2 pixel region 
# in the monochrome image (c) with a red pixel
rccc = (rmask*r + cmask*c).astype(np.uint8)

# RCCC -> GRAY conversion
def rccc_demosaic(rccc, rmask, cmask, filt):
    # RCCC -> GRAY
    # use border type REFLECT_101 to give correct results for border pixels
    filtered = cv2.filter2D(src=rccc, ddepth=-1, kernel=filt, 
                         anchor=(-1, -1), borderType=cv2.BORDER_REFLECT_101)

    demos = (rmask*filtered + cmask*rccc).astype(np.uint8)

    return demos

# demo of the optimal filter
zeta = 0.5
kernel_4neighbor = np.array([[0, 0, 0, 0, 0], 
                             [0, 0, 1, 0, 0], 
                             [0, 1, 0, 1, 0], 
                             [0, 0, 1, 0, 0], 
                             [0, 0, 0, 0, 0]])/4.0
kernel_optimal   = np.array([[0, 0, -1, 0, 0], 
                             [0, 0, 2, 0, 0], 
                             [-1, 2, 4, 2, -1], 
                             [0, 0, 2, 0, 0], 
                             [0, 0, -1, 0, 0]])/8.0
kernel_param     = np.array([[0, 0, -1./4, 0, 0], 
                             [0, 0, 0, 0, 0], 
                             [-1./4, 0, 1., 0, -1./4], 
                             [0, 0, 0, 0, 0], 
                             [0, 0, -1./4, 0, 0]])

# apply optimal filter (Figure 7)
opt1 = rccc_demosaic(rccc, rmask, cmask, kernel_optimal)
# parametric filter with zeta = 0.5 (Figure 5)
opt2 = rccc_demosaic(rccc, rmask, cmask, kernel_4neighbor + zeta * kernel_param)

# PSNR
print(10 * np.log10(255**2/((c - opt1)**2).mean()))
print(10 * np.log10(255**2/((c - opt2)**2).mean()))