Чтение потока изображения с датчика камеры RCCC Bayer в Ubuntu - PullRequest
0 голосов
/ 03 ноября 2018

Я работаю с камерой LI-AR0820 GMSL2, в которой используется датчик On-Semi AR0820, который захватывает изображения в 12-битном формате RCCC Bayer. Я хочу прочитать поток изображений в режиме реального времени с камеры и превратить его в изображение в градациях серого (используя алгоритм демозаики this ), а затем передать его в алгоритм обнаружения объектов. Однако, поскольку OpenCV не поддерживает формат RCCC, я не могу использовать класс VideoCapture для получения данных изображения с камеры. Я ищу что-то похожее, чтобы получить потоковые данные изображения в виде массива, чтобы я мог дальше ими манипулировать. Есть идеи?

Я использую Ubuntu 18.04 с OpenCV 3.2.0 и Python 3.7.1.

РЕДАКТИРОВАТЬ. Я использую код здесь .

#include <vector>
#include <iostream>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

int main() {
    // Each pixel is made up of 16 bits, with the high 4 bits always equal to 0
    unsigned char bytes[2];

    // Hold the data in a vector
    std::vector<unsigned short int> data;

    // Read the camera data
    FILE *fp = fopen("test.raw","rb");
    while(fread(bytes, 2, 1, fp) != 0) {
        // The data comes in little-endian, so shift the second byte right and concatenate the first byte
        data.push_back(bytes[0] | (bytes[1] << 8));
    }

    // Make a matrix 1280x720 with 16 bits of unsigned integers
    cv::Mat imBayer = cv::Mat(720, 1280, CV_16U);

    // Make a matrix to hold RGB data
    cv::Mat imRGB;

    // Copy the data in the vector into a nice matrix
    memmove(imBayer.data, data.data(), data.size()*2);

    // Convert the GR Bayer pattern into RGB, putting it into the RGB matrix!
    cv::cvtColor(imBayer, imRGB, CV_BayerGR2RGB);

    cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE);
    // *15 because the image is dark
    cv::imshow("Display window", 15*imRGB);

    cv::waitKey(0);

    return 0;
}

Есть две проблемы с кодом. Сначала я должен получить необработанный файл изображения с помощью fswebcam, а затем использовать приведенный выше код, чтобы прочитать необработанный файл и отобразить изображение. Я хочу иметь возможность получить доступ к узлу / dev / video1 и напрямую читать необработанные данные оттуда вместо того, чтобы сначала сохранять их, а затем читать отдельно. Во-вторых, OpenCV не поддерживает формат RCCC Bayer, поэтому мне нужно придумать метод демозаики.

Камера выводит сериализованные данные через коаксиальный кабель, поэтому я использую плату Deser с соединением USB 3.0 для подключения камеры к ноутбуку. Настройку можно увидеть здесь .

1 Ответ

0 голосов
/ 11 ноября 2018

Если ваша камера поддерживает свойство CAP_PROP_CONVERT_RGB, вы можете получить необработанные данные RCCC из VideoCapture. Установив для этого свойства значение False, вы можете отключить преобразование в RGB. Таким образом, вы можете захватывать необработанные кадры, используя такой код (без проверки ошибок для простоты):

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()

Я не знаю, работает ли это для вашей камеры.

Если вы можете каким-то образом получить необработанные изображения, вы можете применить метод удаления мозаики, описанный в приложении ANALOG DEVICES.

filter

с оптимальным фильтром

optimal filter

Я написал следующий код на python, как описано в приложении, для проверки преобразования RCCC -> GREY.

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 image :

rgb

Имитированное изображение RCCC:

rccc

Серое изображение из алгоритма удаления мозаики:

gray

Еще одна вещь:

Если поставщик вашей камеры предоставляет SDK для Linux, он может иметь API для преобразования RCCC -> GREY или, по крайней мере, для получения необработанного изображения. Если преобразование RCCC -> GREY отсутствует в SDK, образец кода C # должен иметь его, поэтому я предлагаю вам взглянуть на их код.

...