lenLRX / Atlas_ACL_E2E_Demo

188 stars 38 forks source link

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

Open Lzx1433 opened 1 year ago

Lzx1433 commented 1 year ago

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

lenLRX commented 1 year ago

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

lbhsgdsg commented 1 year ago

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

Lzx1433 commented 1 year ago

`#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

Lzx1433 commented 1 year ago

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

Lzx1433 commented 1 year ago

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