基于OpenCV+QT的实时视频传输显示工具(一)

时常会找一些比较有趣的东西来看,但一般都是看完尝试了事,没怎么做出总结过。现在想想真是可惜,这么多年来,看得东西也不少,但是留下的印记却很少,结果就是找工作时,却拿不出更多的加分项。所以从现在开始,还是做个有心人,慢慢积累,只有自身价值提升了,并且让人看得到,才能获得自己想要的那份报酬。

现在先从OpenCV的使用开始。我始终觉得学习一样东西,单纯学习这个东西是得不到提升的,必须要找到一个立意,构建起一个项目,以项目带动学习,这样理论知识和动手能力都能得到提高。

我的立意就是开发基于OpenCV+QT的实时视频传输显示工具。

基本的思路是实现一个C/S结构。C端实现显示摄像头采集的视频图像,并且在本地利用OpenCV对视频进行处理,并传输视频流。S端接受视频数据,并进行显示。

此过程需要用到的知识如下:

(1)      QT界面

(2)      摄像头视频采集与显示

(3)      OpenCV库使用

(4)      TCP/IP协议

(5)      H264

(6)      多线程编程

(7)      RTMP/RTSP/RTP协议

其中OpneCV、H264以及RTMP/RTSP/RTP对于我来说是两个完全新的东西,需要花点时间学习一下,而其他的基本上温习一下就可以了。

首先需要学习OpenCV的东西。我们可以先用OpenCV实现简单图像的加载和处理,然后再考虑视频的处理。本小节主要先对图形进行加载以及边缘提取,主要代码如下: 

(1)加载图像

voidMainWindow::Loadimage(cv::Mat&mat)

{

    mat=cv::imread("F:\\opencv_test.png");

    if(mat.empty())

    {

        return;

    }

    return;

}

(2)图像格式转换

因为opnencv读取的图片信息为Mat类型的,而QT界面上显示图片时,需要时Qimage类型的,因此还需要将Mat类型图片信息转成Qimage,

boolMainWindow::Mat2Qimage(cv::Mat&mat,QImage&qimage)

{

    if(mat.type()==CV_8UC3)

    {

       qimage=QImage((constunsignedchar*)(mat.data),

                        mat.cols,mat.rows,

                        mat.step,

                        QImage::Format_RGB888).rgbSwapped();

       qimage.save("F:\\opencv_test_out.jpg","JPG");

    }

    elseif(mat.type()==CV_8UC1)

    {

       staticQVector<QRgb>  sColorTable;

       //onlycreateourcolortableonce

       if(sColorTable.isEmpty())

       {

           for(inti=0;i<256;++i)

                sColorTable.push_back(qRgb(i,i,i));

       }

       qimage=QImage((constunsignedchar*)(mat.data),

                     mat.cols,mat.rows,

                    mat.step,

                     QImage::Format_Indexed8);

       //Setthecolortable(usedtotranslatecolourindexestoqRgbvalues)

       qimage.setColorTable(sColorTable);

       qimage.save("F:\\opencv_test_out_gray.jpg","JPG");

    }

    else

    {

       returnfalse;

    }

    returntrue;

}

(3)边缘提取

以下是边缘提取的代码,对图像进行边缘处理需要先进行灰度转换,将图像由3通道的彩色图转换为1通道的灰度图,降噪处理后再进行Canny进行边缘检测

voidMainWindow::on_TransButton_clicked()

{

    QImageqimage;

    cv::MatgrayImage,detected_edges;

    cv::cvtColor(cvimage,grayImage,cv::COLOR_BGR2GRAY);

    cv::blur(grayImage,detected_edges,cv::Size(3,3));

    cv::Canny(detected_edges,detected_edges,threshold,3*threshold,3);

    std::cout<<detected_edges.channels()<<std::endl;

    if(!Mat2Qimage(detected_edges,qimage))

    {

       return;

    }

    ui->trans_view_label->setPixmap(QPixmap::fromImage(qimage));

}

 

另外还做了其他转换,将获取的边缘图像作为掩码拷贝到原图上,形成彩色的边缘图,效果如下,具体做法大家可以自己去百度,网上应该有很多这样的用法。

 

猜你喜欢

转载自blog.csdn.net/u011337602/article/details/79561457