lenLRX/Atlas_ACL_E2E_Demo

询问是否支持USB摄像头的输入?

Opened this issue · 5 comments

这边拓展了一个USB槽,目前使用了opencv的videocapture已经能正确读取摄像头的帧,想咨询一下能否在此程序的基础上改成能输入为USB摄像头?是否需要进行进一步的视频画面转码或者解码,十分感谢

lenLRX commented

如果你已经打通了驱动,那就没问题。USB摄像头输入的一般是像素帧,不需要解码,但是你要搞清楚是RGB还是YUV什么格式的,如果是YUV420SP的格式,就不需要转码。
具体的代码可以参考原本atlas200DK的板载摄像头的代码:https://github.com/lenLRX/Atlas_ACL_E2E_Demo/blob/master/src/camera_input.h

请问你解决了,怎么改成输入为USB摄像头,我不太会

`#include "camera_input.h"
#include "app_profiler.h"
#include "dev_mem_pool.h"
#include "util.h"
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;

int CameraInput::Init(int id) {
camera_id = id;

cam.open(-1);
//cam.set(CV_CAP_PROP_CONVERT_RGB, 0);
//cam.set(CV_CAP_PROP_MODE, CV_CAP_MODE_YUYV);
int error= 9999999;
if(!cam.isOpened())
{
std::cout<<error<<std::endl;
}
else{
std::cout<<running<<std::endl;
}
width = cam.get(CAP_PROP_FRAME_WIDTH);
height = cam.get(CAP_PROP_FRAME_HEIGHT);
fps = cam.get(CAP_PROP_FPS);
cam_buffer_size = yuv420sp_size(height, width);
return 0;
}

void CameraInput::Run() {
while (running) {
cv::Mat frameIn;
cv::Mat frame(720,640,CV_8UC1);
cv::Mat outimg(720,640,CV_8UC1);
APP_PROFILE(CameraInput::Run);
cam.read(frameIn);
cv::cvtColor(frameIn,frame,CV_BGR2YUV_I420);
unsigned char* i420bytes=frame.data;
unsigned char* nv12bytes=outimg.data;
//tonv12

int nLenY = width * height*3/2;
int nLenU = nLenY / 4;

memcpy(nv12bytes, i420bytes, width * height*3/2);

for (int i = 0; i < nLenU; i++)
{
    nv12bytes[nLenY + 2 * i] = i420bytes[nLenY + i];                    // U
    nv12bytes[nLenY + 2 * i + 1] = i420bytes[nLenY + nLenU + i];        // V
}
//cv::imwrite("./out.jpg",outimg);
// uint8_t *camera_buffer = (uint8_t *)malloc(cam_buffer_size);
unsigned char* camera_buffer =(unsigned char*) DevMemPool::AllocDvppMem(cam_buffer_size);
memcpy(camera_buffer, outimg.data, cam_buffer_size);
auto dev_cam_buffer = std::make_shared<DeviceBuffer>(
    camera_buffer, cam_buffer_size, DeviceBuffer::DvppMemDeleter());
output_queue->push(dev_cam_buffer);

}
}

CameraInput::~CameraInput() {}

void CameraInput::SetOutputQueue(
ThreadSafeQueueWithCapacity *queue) {
output_queue = queue;
}

int CameraInput::GetHeight() { return height; }

int CameraInput::GetWidth() { return width; }

int CameraInput::GetFPS() { return fps; }

void CameraInput::Stop() { running = false; cam.release(); }
`
这是我修改的camera.cpp的代码 从opencv的videocapture进行usb摄像头的读取并且将读取的frame转换为了yuv420sp的格式,并送到了camerabuffer当中,但是运行的时候会报如下的错误,感觉像是内存相关的问题,但是一直没有什么头绪,请问作者能帮忙看看吗?
image

目前已经找到了大概的问题所在,把YUV_I420转YUV420SP的代码暂时去掉后,能够正常的推流并显示,估计问题出在memcpy(nv12bytes, i420bytes, width * height*3/2); 但是目前输出I420的画面颜色很明显是不对的,但是一旦加入了转yuv420sp的代码后就会报内存的错误

问题解决了,是宽度设置错误,传进转YUV420sp的height不需要乘1.5