手上有一塊RK3568板子,正好官方SDK提供了opencv和QT的環(huán)境,就整個QT+OPENCV的簡單應(yīng)用玩玩。老鐵們可以從整個簡單示例開始疊加復(fù)雜功能了。
配置編譯文件
直接在qt的配置文件中添加opencv庫即可。
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = usbcamera_gui
TEMPLATE = app
#LIBS += -L. -ljpeg
CONFIG +=gnu++11 -Wl,--allow-shlib-undefined
LIBS += -L. -lopencv_core -lopencv_objdetect -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgproc -lopencv_imgcodecs -lrknn_api -lOpenCL -lpthread
QTPLUGIN += qjpeg
LIBS += -L../../../../../../tools/pack/chips/sun8iw11p1/hal/gpu/fbdev/lib/ -lGLESv2
SOURCES += main.cpp\
camera.cpp
HEADERS += camera.h
FORMS += camera.ui
處理圖像
這里直接使用USB采集的圖像進行處理。通過ioctl配置參數(shù)。就取了個640*480分辨來看看效果。
int camera::camera_init()
{
int ret=0,i=0,count=0;
struct v4l2_capability cap;
struct v4l2_fmtdesc fmtdesc;
struct v4l2_format format;
struct v4l2_requestbuffers reqbuf;
struct v4l2_buffer buf;
fmtdesc.index = 0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ::ioctl(fd, VIDIOC_G_FMT, &format);
if(ret < 0){
perror("VIDIOC_G_FMT");
exit(1);
}
printf("width:%d\n", format.fmt.pix.width);
printf("height:%d\n", format.fmt.pix.height);
printf("pixelformat:%x\n", format.fmt.pix.pixelformat);
printf("field:%x\n", format.fmt.pix.field);
printf("bytesperline:%d\n", format.fmt.pix.bytesperline);
printf("sizeimage:%d\n", format.fmt.pix.sizeimage);
printf("colorspace:%d\n", format.fmt.pix.colorspace);
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.fmt.pix.width = 640;
format.fmt.pix.height = 480;
format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
ret = ::ioctl(fd, VIDIOC_S_FMT, &format);
if(ret < 0){
fprintf(stderr, "Not support jepg");
perror("VIDIOC_S_FMT");
exit(1);
}
reqbuf.count = 3;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_MMAP;
ret = ::ioctl(fd, VIDIOC_REQBUFS, &reqbuf);
if(ret < 0){
perror("VIDIOC_REQBUFS");
exit(1);
}
bufinf = (struct bufinfor *)calloc(reqbuf.count, sizeof(struct bufinfor));
if(!bufinf){
perror("calloc");
exit(1);
}
for(count = 0; count < reqbuf.count; count++){
buf.index = count;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ret = ::ioctl(fd, VIDIOC_QUERYBUF, &buf);
if(ret < 0){
perror("VIDIOC_REQBUFS");
exit(1);
}
bufinf[buf.index].length = buf.length;
bufinf[buf.index].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
if(!(bufinf[buf.index].start)){
perror("mmap");
exit(1);
}
}
for(i = 0; i < reqbuf.count; i++){
buf.index = i;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ret = ::ioctl(fd, VIDIOC_QBUF, &buf);
if(ret < 0){
perror("VIDIOC_QBUF");
exit(1);
}
}
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ::ioctl(fd, VIDIOC_STREAMON, &type);
if(ret < 0){
perror("VIDIOC_STREAMON");
exit(1);
}
return 0;
}
還是通過ioctl映射出原始的圖像數(shù)據(jù),這里將圖像的YUV數(shù)據(jù)轉(zhuǎn)為bgr。在opencv中一般輸入的是bgr圖像進行處理。
unsigned char *bgr=new unsigned char [640 * 480 *3];
struct v4l2_buffer buf;
fd_set readset;
FD_ZERO(&readset);
FD_SET(fd, &readset);
ret = select(fd + 1, &readset, NULL, NULL, NULL);
if(ret < 0){
perror("select");
exit(1);
}
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd, VIDIOC_DQBUF, &buf);
if(ret < 0){
perror("VIDIOC_DQBUF");
exit(1);
}
convert_yuv_to_bgr_buffer((unsigned char *)bufinf[buf.index].start,bgr,640,480);
ret = ioctl(fd, VIDIOC_QBUF, &buf);
if(ret < 0){
perror("VIDIOC_QBUF");
exit(1);
}
處理圖像
將bgr數(shù)據(jù)導(dǎo)入Mat數(shù)據(jù),注意opencv中使用的是行和列,即cols和rows,cols就是圖像的寬度width,rows就是圖像的高度height。所以這里是480, 640。下面就是opencv的常規(guī)操作了。
Mat img = Mat(480, 640, CV_8UC3, bgr, 0);
Mat dstImage, edge, grayImage;
dstImage.create(img.size(), img.type() );
cvtColor(img, grayImage, CV_BGR2GRAY);
blur(grayImage, edge, Size(3,3) );
Canny(edge, edge, 10, 30, 3 );
cvtColor(edge, dstImage, CV_GRAY2BGR);
addWeighted(img, 1, dstImage, 0.5, 1, img);
putText(img, "QT+OPENCV", Point(120,100),FONT_HERSHEY_TRIPLEX,2,0,2,8);
顯示圖像
QT一般使用的是RGB圖像,所以注意得轉(zhuǎn)換一下,不然那顏色就反了。將Mat圖像數(shù)據(jù)轉(zhuǎn)為QImage即可。
cvtColor(img, dstImage, CV_BGR2RGB);
QImage *mage = new QImage(dstImage.data,640,480,QImage::Format_RGB888);
QImage resultimg=mage->scaled(ui->label->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation);
ui->label->setPixmap(QPixmap::fromImage(resultimg, Qt::AutoColor));
如此一個簡易的QT+Opencv應(yīng)用就完成了。工程附上,老鐵們可以開始進階了。文章來源:http://www.zghlxwxcb.cn/news/detail-533663.html
QT+Opencv的應(yīng)用示例文章來源地址http://www.zghlxwxcb.cn/news/detail-533663.html
到了這里,關(guān)于ARM應(yīng)用之瑞芯微RK3568上使用QT+Opencv的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!