时常会找一些比较有趣的东西来看,但一般都是看完尝试了事,没怎么做出总结过。现在想想真是可惜,这么多年来,看得东西也不少,但是留下的印记却很少,结果就是找工作时,却拿不出更多的加分项。所以从现在开始,还是做个有心人,慢慢积累,只有自身价值提升了,并且让人看得到,才能获得自己想要的那份报酬。
现在先从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));
}
另外还做了其他转换,将获取的边缘图像作为掩码拷贝到原图上,形成彩色的边缘图,效果如下,具体做法大家可以自己去百度,网上应该有很多这样的用法。