软件设计任务概述

本次的实验在实验八的基础上进行整合,删除冗余的函数和操作按钮,修改不必要的跳转函数,优化处理,完成对视频、图像的操作。

本次的实验平台搭建用QT Create 和Opencv 一同完成。在对图片处理的过程中,只调用QT的库函数对图片的像素的Rgb进行处理,在对视频的处理上,调用Opencv 的库函数操作。在本次的实验分成两部分进行:一、对图片进行处理;二、完成对视频的处理。具体要求如下:

  1. 图像处理:对图像进行灰度化、二值化(阈值可调)、均值滤波、伽马变换(针对彩图)、边缘检测、高斯模糊、加水印、图片导出保存等功能。
  2. 视频处理:对每帧视频帧进行灰度化、二值化、边缘检测、缩放、局部马赛克等操作。

二、可行性研究、需求分析及分工 

2.1、可行性研究

在实验八的基础上可知,Qt调用C/C++库函数可以完成对图像(QImage)的像素点的处理,所有在接下里的二值化等需求也是可行的,在查阅了相关的资料后得知,opencv可以对视频经行切片处理,获得帧,从而对视频经行转帧播放,同时在对帧即图像可以处理,所有视频的灰度化等是可行的。

2.2、需求分析

对图片的处理是对像素点的处理,根据之前的方法知道,没有另外的需求。对视频的处理需要在QT中加入Opencv的库函数,调用 VideoCapture capture 来对视频进行分析和操作。

三、实现的过程与步骤

3.1、基本界面的搭建

注意点在于:

1.对mainToolBar的引入是不可以直接的,因为在工具库中是没有这个工具的,所以在项目外打开 .ui 文件 在文件中加入下列代码实现对mainToolBar 的添加。

<widget class="QToolBar" name="mainToolBar"><property name="toolButtonStyle"><enum>Qt::ToolButtonIconOnly</enum></property><attribute name="toolBarArea"><enum>TopToolBarArea</enum></attribute><attribute name="toolBarBreak"><bool>false</bool></attribute></widget>

2.在之前实践的基础上,将减少不必要的操作,放入工具栏和两个Dock栏(左侧的是对图片的处理,右侧的是对视频的处理),在中间打破centralwidget布局,放入三个label,两个用来显示图片,在打开图片时隐藏一个(originMovieLabel),打开视频是,隐藏另外两个(originLabel、showLabel)。隐藏和显示的代码如下:

ui->originMovieLabel->setVisible(false);

运行效果如下:

3.2、警告窗口

在本次的作用要求中,对提示警告窗进行了详细的制作,在其中加入图片和图标,和主窗口对应,相关代码和运行效果如下:

代码如下:

QMessageBox *msgBox=new QMessageBox();
msgBox->setWindowTitle(tr("关于本软件对话框"));
msgBox->setIconPixmap(QPixmap(":/img/img/warning.png"));
QIcon icon(":/img/img/need_icon.ico");
msgBox->setInformativeText(tr("没有图片"));
msgBox->setStyleSheet("QLabel{""min-width: 200px;""min-height: 100px; ""}");
msgBox->setWindowIcon(icon);
msgBox->show();

3.3、图像处理

在对图像处理中梳理其核心为对其与周边像素的处理,在此出对本软件的部分实现算法做一份介绍,如:灰度处理、均值滤波、二值化、边缘检测、伽马处理。

3.3.1、读入文件

调用QFileDialog读入文件,获得文件的地址信息,打开文件。如果打开失败,弹出提醒弹窗,读入成功,在originLabel中显示。

3.3.2、灰度处理

获得originLabel中的图片,对Qpixmap对象转变为QImage对象,获得图像的像素,获得其RGB的值,然后通过灰度公式对其进行计算,得出最后的RGB值,然后重新赋值给这个像素点,将像素点放回到图像从而得到最后的处理图像,显示在showlabel中。(这里用的是加权的计算方法)运行结果(图4-5)和代码如下:

QImage MainWindow::grayscale1(){QImage *origin =new QImage();、/*警告模块,参考上述3.2的代码内容*/*origin =ui->originLabel->pixmap()->toImage();QImage *newImage = new QImage(origin->width(), origin->height(), QImage::Format_ARGB32);for(int y = 0; y<newImage->height(); y++){//获取一行像素的首地址QRgb * line = (QRgb *)origin->scanLine(y);for(int x = 0; x<newImage->width(); x++){//提取像素//灰度转换的一种方法(R G B 求平均值)int average = (qRed(line[x])*0.299 + qGreen(line[x])*0.587 + qBlue(line[x])*0.114);newImage->setPixel(x,y, qRgb(average, average, average));}}return *newImage;}

3.3.3、二值化处理

同上,获得图像的像素点,设置阈值,将图像灰度化处理,比较像素点灰度值与阈值的关系,大于设为黑色,即RGB(0,0,0);反正着设为RGB(255,255,255),组合显示。运行效果(图4-6)和代码如下:

QImage MainWindow::bianry1(QImage origin){/*警告模块,参考上述3.2的代码内容*/QImage *newImage=new QImage(origin.width(), origin.height(), QImage::Format_ARGB32);for(int y = 0; y<newImage->height(); y++){//获取一行像素的首地址QRgb * line = (QRgb *)origin.scanLine(y);for(int x = 0; x<newImage->width(); x++){//提取像素int rgb_r=qRed(line[x]);if(rgb_r<=int(num)){newImage->setPixel(x,y, qRgb(255,255,255));}else{newImage->setPixel(x,y, qRgb(0,0,0));}}}return *newImage;}

3.3.4、均值滤波(阈值可调)

同上,先获得像素点,然后根据所提供的阈值将所在的矩形(其为中心)的所有像素的RGB的值都相加,同时统计加入了几个像素点。计算出其平均值后再赋值,找下一个像素点重复上述的操作,以此达到对均值滤波的效果。此处的注意点在于对边界的判定和对像素点个数的判定。代码运行与截图(4-7)如下:(注意:此处代码有误,bug点应该在对便捷判断的地方,两层循环的里面的if ,自行改正啦,不然运行会出黑边

QImage MainWindow::average1(){
QImage *origin =new QImage();/*警告模块,参考上述4.2的代码内容*/*origin =ui->originLabel->pixmap()->toImage();QImage *newImage = new QImage(origin->width(), origin->height(), QImage::Format_ARGB32);qDebug()<<num;for(int y = 0; y<newImage->height(); y++){//获取一行像素的首地址QRgb * line = (QRgb *)origin->scanLine(y);for(int x = 0; x<newImage->width(); x++){//1.设法提去周边的数组int sum=0;double rgb_r=0;double rgb_b=0;double rgb_g=0;for(int y1=y-int(num/2);y1<(y+int(num/2));y1++){for(int x1=x-int(num/2);x1<(x+int(num/2));x1++){if(x1<0||y1<0||x1>x||y1>y) {break;}else{rgb_r=rgb_r+qRed(line[x1]);rgb_g=rgb_g+qGreen(line[x1]);rgb_b=rgb_b+qBlue(line[x1]);sum++;}}}//2.计算平均值//3.放回数值          newImage->setPixel(x,y,qRgb(int(rgb_r/sum),int(rgb_g/sum),int(rgb_b/sum)));}}//4.打印照片return *newImage;}

3.3.5、边缘检测算法

本算法的实现采用canny算法,其先对图像进行灰度的处理,在进行高斯平滑算法处理,降低其噪点的存在,再计算梯度强度和方向,对图像非最大值进行抑制,双阀值检测与抑制孤立低阈值点,减少早点的存在,使图片的效果更加清晰,最后得出边缘检测的图。本处的代码较多,不做展示,详情看源码文件。运行截图如下:

相关整合代码如下:提供参照文档

QImage MainWindow::By1(QImage image){QImage *img =new QImage();*img=image;QImage img_gray=image;// QImage img_guass;//**********高斯模糊开始int k=5;//高斯滤波器规模double kernel[10][10];generic_guess(kernel,k,1.4);QImage * t_img=new QImage(img_gray.width()+k-1,img_gray.height()+k-1,QImage::Format_ARGB32);QImage *img_guass=new QImage(img_gray.width(),img_gray.height(),QImage::Format_ARGB32);//lefttopfor(int i=0;i<k/2;++i){for(int j=0;j<k/2;++j){t_img->setPixel(i,j,img_gray.pixel(0,0));}}//righttopfor(int i=0;i<k/2;++i){for(int j=0;j<k/2;++j){t_img->setPixel(i,j,img_gray.pixel(img_gray.width()-1,0));}}//rightbottomfor(int i=img_gray.width()+k/2;i<t_img->width();++i){for(int j=0;j<k/2;++j){t_img->setPixel(i,j,img_gray.pixel(img_gray.width()-1,img_gray.height()-1));}}//leftbottomfor(int i=0;i<k/2;++i){for(int j=img_gray.height()+k/2;j<t_img->height();++j){t_img->setPixel(i,j,img_gray.pixel(0,img_gray.height()-1));}}//topfor(int i=0;i<img_gray.width();++i){for(int j=0;j<k/2;++j){t_img->setPixel(i+k/2,j,img_gray.pixel(i,0));}}//rightfor(int i=t_img->width()-k/2;i<t_img->width();++i){for(int j=0;j<img_gray.height();++j){t_img->setPixel(i,j+k/2,img_gray.pixel(img_gray.width()-1,j));}}//bottomfor(int i=0;i<img_gray.width();++i){for(int j=t_img->height()-k/2;j<t_img->height();++j){t_img->setPixel(i+k/2,j,img_gray.pixel(i,img_gray.height()-1));}}//leftfor(int i=0;i<k/2;++i){for(int j=0;j<img_gray.height();++j){t_img->setPixel(i,j+k/2,img_gray.pixel(0,j));}}for(int i=0;i<img_gray.width();++i){for(int j=0;j<img_gray.height();++j){t_img->setPixel(i+k/2,j+k/2,img_gray.pixel(i,j));}}for(int i=k/2;i<t_img->width()-k/2;++i){for(int j=k/2;j<t_img->height()-k/2;++j){double temp=0;for(int ti=0;ti<k;++ti){for(int tj=0;tj<k;++tj){temp+=kernel[ti][tj]*qRed(t_img->pixel(i-k/2+ti,j-k/2+tj));}}img_guass->setPixel(i-k/2,j-k/2,qRgb(temp,temp,temp));}}
//**************高斯模糊结束、end
//**************计算梯度强度和方向开始double** gradx=new double*[img->width()];for(int i=0;i<img->width();++i)gradx[i]=new double[img->height()];double** grady=new double*[img->width()];for(int i=0;i<img->width();++i)grady[i]=new double[img->height()];double** grad=new double*[img->width()];for(int i=0;i<img->width();++i)grad[i]=new double[img->height()];double** dir=new double*[img->width()];for(int i=0;i<img->width();++i)dir[i]=new double[img->height()];int k1=3;//sobel算子规模double kernelx[3][3]={-1,0,1,-2,0,2,-1,0,1};double kernely[3][3]={1,2,1,0,0,0,-1,-2,-1};QImage *t_img1=new QImage(img_gray.width()+k1-1,img_gray.height()+k1-1,QImage::Format_ARGB32);//lefttopfor(int i=0;i<k1/2;++i){for(int j=0;j<k1/2;++j){t_img1->setPixel(i,j,img_gray.pixel(0,0));}}//righttopfor(int i=0;i<k1/2;++i){for(int j=0;j<k1/2;++j){t_img1->setPixel(i,j,img_gray.pixel(img_gray.width()-1,0));}}//rightbottomfor(int i=img_gray.width()+k1/2;i<t_img1->width();++i){for(int j=0;j<k1/2;++j){t_img1->setPixel(i,j,img_gray.pixel(img_gray.width()-1,img_gray.height()-1));}}//leftbottomfor(int i=0;i<k1/2;++i){for(int j=img_gray.height()+k1/2;j<t_img1->height();++j){t_img1->setPixel(i,j,img_gray.pixel(0,img_gray.height()-1));}}//topfor(int i=0;i<img_gray.width();++i){for(int j=0;j<k1/2;++j){t_img1->setPixel(i+k1/2,j,img_gray.pixel(i,0));}}//rightfor(int i=t_img1->width()-k1/2;i<t_img1->width();++i){for(int j=0;j<img_gray.height();++j){t_img1->setPixel(i,j+k1/2,img_gray.pixel(img_gray.width()-1,j));}}//bottomfor(int i=0;i<img_gray.width();++i){for(int j=t_img1->height()-k1/2;j<t_img1->height();++j){t_img1->setPixel(i+k1/2,j,img_gray.pixel(i,img_gray.height()-1));}}//leftfor(int i=0;i<k1/2;++i){for(int j=0;j<img_gray.height();++j){t_img1->setPixel(i,j+k1/2,img_gray.pixel(0,j));}}for(int i=0;i<img_gray.width();++i){for(int j=0;j<img_gray.height();++j){t_img1->setPixel(i+k1/2,j+k1/2,img_gray.pixel(i,j));}}for(int i=k1/2;i<t_img1->width()-k1/2;++i){for(int j=k1/2;j<t_img1->height()-k1/2;++j){double tempx=0;double tempy=0;for(int ti=0;ti<k1;++ti){for(int tj=0;tj<k1;++tj){tempx+=kernelx[ti][tj]*qRed(t_img1->pixel(i-k1/2+ti,j-k1/2+tj));tempy+=kernely[ti][tj]*qRed(t_img1->pixel(i-k1/2+ti,j-k1/2+tj));}}gradx[i-k1/2][j-k1/2]=tempx;//errorgrady[i-k1/2][j-k1/2]=tempy;grad[i-k1/2][j-k1/2]=sqrt(pow(tempx,2)+pow(tempy,2));double theta=atan(tempy/tempx)+90;if (theta >= 0 && theta < 45)dir[i-k1/2][j-k1/2] = 2;else if (theta >= 45 && theta < 90)dir[i-k1/2][j-k1/2] = 3;else if (theta >= 90 && theta < 135)dir[i-k1/2][j-k1/2] = 0;elsedir[i-k1/2][j-k1/2] = 1;}}bool calcu=true;
//***********************计算梯度强度和方向结束
//***********************非极大值抑制开始if(!calcu){QMessageBox::critical(this,u8"提示",u8"未计算边缘强度和方向");}QColor c1(255,255,255);QColor c(0,0,0);QRgb edge = qRgb(c.red(),c.green(),c.blue());QRgb notedge = qRgb(c1.red(),c1.green(),c1.blue());QImage *img_nms=new QImage(img_guass->width(),img_guass->height(),QImage::Format_ARGB32);double temp=0;for(int i=0;i<img_nms->width();++i){for(int j=0;j<img_nms->height();++j){temp+=grad[i][j];}}temp/=img_nms->width()*img_nms->height();double highthresh =temp;double lowthresh=highthresh;double N,NE,E,SW,W,SE,S,NW;double grad1=0,grad2=0,tantheta=0;for(int i=1;i<img_nms->width()-1;++i){for(int j=1;j<img_nms->height();++j){N=grad[i][j-1];NE=grad[i+1][j-1];E=grad[i+1][j];SW=grad[i-1][j+1];W=grad[i-1][j];SE=grad[i+1][j+1];S=grad[i][j+1];NW=grad[i-1][j-1];if(dir[i][j]==0){tantheta=abs(grady[i][j]/gradx[i][j]);grad1=E*(1-tantheta)+NE*tantheta;grad2=W*(1-tantheta)+SW*tantheta;}else if(dir[i][j]==1){tantheta=abs(gradx[i][j]/grady[i][j]);grad1=N*(1-tantheta)+NE*tantheta;grad2=S*(1-tantheta)+SW*tantheta;}else if(dir[i][j]==2){tantheta=abs(gradx[i][j]/grady[i][j]);grad1=N*(1-tantheta)+NW*tantheta;grad2=S*(1-tantheta)+SE*tantheta;}else if(dir[i][j]==3){tantheta=abs(grady[i][j]/gradx[i][j]);grad1=W*(1-tantheta)+NW*tantheta;grad2=E*(1-tantheta)+SE*tantheta;}else{grad1=highthresh;grad2=highthresh;}if(grad[i][j]>grad1&&grad[i][j]>grad2){img_nms->setPixel(i,j,edge);//black边缘//                gradcp[i][j]=highthresh;}else{img_nms->setPixel(i,j,notedge);//whitegrad[i][j]=0;}}}
//************非极大值抑制结束
//************双阈值检测开始QImage *img_dt=new QImage(img_nms->width(),img_nms->height(),QImage::Format_ARGB32);double** gradcp=new double*[img->width()];for(int i=0;i<img->width();++i)gradcp[i]=new double[img->height()];for(int i=0;i<img_dt->width();++i){for(int j=0;j<img_dt->height();++j){if(grad[i][j]>highthresh){//强边缘gradcp[i][j]=highthresh;img_dt->setPixel(i,j,edge);}else if(grad[i][j]>lowthresh){//弱边缘gradcp[i][j]=lowthresh;img_dt->setPixel(i,j,edge);}else{//非边缘gradcp[i][j]=0;img_dt->setPixel(i,j,notedge);//抑制}}}//************双阈值检测结束
//************抑制孤立低阈值点开始QImage *img_st=new QImage(img_dt->width(),img_dt->height(),QImage::Format_ARGB32);int frac[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};for(int i=1;i<img_st->width()-1;++i){for(int j=1;j<img_st->height()-1;++j){if(gradcp[i][j]==highthresh){//强边缘img_st->setPixel(i,j,edge);}else if(gradcp[i][j]==lowthresh){//弱边缘for(int p=0;p<8;++p){if(gradcp[i+frac[p][0]][j+frac[p][1]]==highthresh){img_st->setPixel(i,j,edge);//边缘break;}img_st->setPixel(i,j,notedge);//非边缘}}else//非边缘img_st->setPixel(i,j,notedge);}}
//*******最终结果如下return *img_st;/*}return *img;*/
}

如各位所见,代码量很大,而且...不是自己纯原创的

参考文档:边缘检测之Canny算法_Qt实现(C++)

3.3.6、伽马转变

伽马转变是在图像处理中,将漂白或曝光过头或不足的照片经行修正,根据伽马变换的公式与其图像可知:gamma值小于1时,会拉伸图像中灰度级较低的区域,同时会压缩灰度级较高的部分;gamma值大于1时,会拉伸图像中灰度级较高的区域,同时会压缩灰度级较低的部分。获得图像的像素后,将其每一个RGB的值经行一次公式的运行后放回,得到相关的图片。运行截图与代码如下:

QImage MainWindow::gamma1(){QImage *image=new QImage();/*警告模块,参考上述3.2的代码内容*/*image=ui->originLabel->pixmap()->toImage();double d=num;QColor color;int height = image->height();int width = image->width();for (int i=0;i<width;i++){for(int j=0;j<height;j++){color = QColor(image->pixel(i,j));double r = color.red();double g = color.green();double b = color.blue();int R = qBound(0,(int)qPow(r,d),255);int G = qBound(0,(int)qPow(g,d),255);int B = qBound(0,(int)qPow(b,d),255);image->setPixel(i,j,qRgb(R,G,B));}}return *image;}

4.3.7、保存图片

获得showlabel中的图片信息,调用QPixmap的save()函数,使得可以保存图片,同时读取系统时间,将其作为命名的标题保存地址为程序编译的地址。相关代码如下:

void MainWindow::save(){QImage *image =new QImage();/*警告模块,参考上述3.2的代码内容*/*image = ui->showLabel->pixmap()->toImage();QPixmap p =QPixmap::fromImage(*image);//文件命名系统QTime current_time =QTime::currentTime();int hour = current_time.hour();//当前的小时int minute = current_time.minute();//当前的分int second = current_time.second();//当前的秒QString filename=QString::number(hour)+"_"+QString::number(minute)+"_"+QString::number(second)+"_"+QString::number(num)+".jpg";//保存图片p.save(filename,Q_NULLPTR,100);qDebug()<<"ok";}

3.4、视频处理

在本处的视频处理中,引入opencv作为对视频的处理。将视频读入后,获得其每一帧的图像,然后处理

3.4.1、安装OpenCV

在安装过程中注意其的报错,有可能就因为网络问题出现无法下载相关的库文件,在写函数的时候使无法发现的,但在运行的时候才会发现库文件的确实,最容易出错的为:opencv_ffmpeg_64.dllffmpeg_version.cmakeopencv_ffmpeg.dll

相关的参考资料如下:

1.OpenCV安装教程  基于64位win10系统的QT+opencv环境配置_huadianyue的专栏-CSDN博客_opencv qt win10

2.OpenCV Cmake-Configure报错的解决教程:

CMake opencv时Download: opencv_ffmpeg.dll、ippicv等失败的解决方法_楷尘·极客-CSDN博客_opencv_ffmpeg.dll下载

  1. 相关库文件国内映射口与ffmpeg_version.cmake下载问题:

CMake编译OpenCV4.0时opencv_ffmpeg.dll等下载失败的解决思路总结 - 葫芦娃508 - 博客园

3.4.2、对.opr文件的操作

在安装完openCV后,需要在.opr文件中添加以下的信息(地址为你的配置地址):

INCLUDEPATH +=D:/qt/opencv-4.5.4/opencvlib/install/include
INCLUDEPATH +=D:/qt/opencv-4.5.4/opencvlib/install/include/opencv
INCLUDEPATH +=D:/qt/opencv-4.5.4/opencvlib/install/include/opencv2
LIBS +=D:/qt/opencv-4.5.4/opencvlib/install/x64/mingw/lib/libopencv_*.a

3.4.3、读取视频文件

在函数中调用QFileDialog读入文件,获得文件的地址信息,打开视频文件,调用capture.open(video_path.toStdString());打开视频。用capture.isOpened()判断文件是否正确打开。没有提供相关的警告弹窗。打开视频就让前面显示图片的label暂时消失,并且显示originMovieLabel。计算帧率和视频时间。值得注意的是:在本段代码里需要注意的是,opencv用的是String类型的字符串,但QT用的是QString类型的字符串,其不是一样的,需要进行处理和转置,其中可能出现乱码的可能性。相关代码与截图(图4-10)如下:

void MainWindow::openMovie(){QString video_path = QFileDialog::getOpenFileName(this,tr("选择视频"),"E:/Qt/qtworks/MainWindow/images",tr("Video (*.WMV *.mp4 *.rmvb *.flv)"));if(video_path!=nullptr){//打开视频文件:其实就是建立一个VideoCapture结构capture.open(video_path.toStdString());//检测是否正常打开:成功打开时,isOpened返回tureif (!capture.isOpened()){/*警告模块,参考上述3.2的代码内容*///对label的管理ui->showLabel->setVisible (false);//让他暂时消失ui->originLabel->setVisible (false);//让他暂时消失ui->originMovieLabel->setVisible(true);//视频部分显示出来//获取整个帧数long totalFrameNumber = capture.get(CAP_PROP_FRAME_COUNT);//设置开始帧()long frameToStart = 0;capture.set(CAP_PROP_POS_FRAMES, frameToStart);//获取帧率double rate = capture.get(CAP_PROP_FPS);delay = 1000 / rate;timer.start(delay);type=0;//timer.start();isstart=!isstart;isMovie=1;isPhoto=0;isPhoto_r=0;}
}

4.4.4、视频播放与视频处理

其原理是调用MAT对象的函数,获得视频的帧,对帧进行操作,然后返回继续显示,在不断的重复中输出处理后的视频图像。本次实验实验对视频的二值化处理、灰度处理、边缘检测处理、马赛克、缩放的处理。

  1. 二值化

调用了opencv的自带函数threshold(frame, frame,too, 255, THRESH_BINARY);将Mat对象处理返回,然后转化图像显示。相关运行截图(图4-11)如下。

  1. 灰度处理

对视频的灰度处理也是调用系统函数cvtColor(frame,frame,CV_BGR2GRAY);,不然其无法平滑播放。相关运行截图如下。

  1. 视频边缘检测处理

边缘检测调用前面对图像的处理,使其完成边缘检测,但因为要循环的数据过大,使其无法平稳的播放。相关运行截图如下。

  1. 视频马赛克处理(阈值可调)

与上述的均值有些相似,划定一个大小的矩阵,遍历矩阵中的所有像素,将矩阵最开始的像素的值赋值给所有的点,然后输入。相关截图如下。

马赛克的相关代码

Mat MainWindow::masaike(Mat src){int width = src.rows;  //图片的长度int height = src.cols;  //图片的宽度if(scale==NULL){scale=10;}int arr = scale;//试图调节//i和j代表了矩形区域的左上角的像素坐标for (int i = 0; i < width; i+=arr) {//int i = width/2.5; i < width/1.5; i+=arrfor (int j = 0; j < height; j+=arr) {//int j = height/2.5; j < height/1.5; j+=arr//对矩形区域内的每一个像素值进行遍历for (int k = i; k < arr + i && k < width; k++) {for (int m = j; m < arr + j && m < height; m++) {//在这里进行颜色的修改//at<Vec3b>(k, m)[0]=qRed();取出像素点中的rgb三数值,不过这里是对数组的形式src.at<Vec3b>(k, m)[0] = src.at<Vec3b>(i, j)[0];//Bsrc.at<Vec3b>(k, m)[1] = src.at<Vec3b>(i, j)[1];//Gsrc.at<Vec3b>(k, m)[2] = src.at<Vec3b>(i, j)[2];//R}}}}return src;
}

最后放上参考文档:使用QT5+Opencv完成简单的图像处理及视频处理软件_每天进步一点点!-CSDN博客_opencv图像处理软件

QT 大作业实现对图片与视频的处理相关推荐

  1. qt大作业——消灭星星

    qt大作业--消灭星星 暑假大作业qt--消灭星星 暑假大作业qt--消灭星星 这是我作业写的代码,可以运行,而且内容十分丰富 链接: 工程下载.

  2. 大作业,但是图片不会传

    计算机系统 大作业 题     目 程序人生-Hello's P2P 专       业 计算机 计算机科学与技术学院 2021年5月 摘  要 摘要是论文内容的高度概括,应具有独立性和自含性,即不阅 ...

  3. QT大作业:学生管理系统(通过mysql数据库)

    一.前言 学校实验室进行第二轮考核,第二次qt作业是学生管理系统. 要求如下: 1.连接数据库,对学生信息进行增删改查操作,可以使用qt的SQLITE,但大家需自行学习sql语句的语法才能实现相关功能 ...

  4. QT大作业之---学生信息管理系统

    金樽清酒斗十千,玉盘珍羞直万钱. 停杯投箸不能食,拔剑四顾心茫然. 欲渡黄河冰塞川,将登太行雪满山. 闲来垂钓碧溪上,忽复乘舟梦日边. 行路难!行路难!多歧路,今安在? 长风破浪会有时,直挂云帆济沧海 ...

  5. QT大作业——自制小游戏

    The RPGgame with QT 一. 系统架构 该项目有4个ui组成,其中mainwindow作为项目程序入口,窗口跳转流程为:mainwindow->gamegraph->are ...

  6. web大二实训作业:校园运动会网站设计——运动会图片轮播图片遮罩特效(4页)体育 HTML+CSS+JavaScript HTML5期末大作业...

    常见网页设计作业题材有 ​​个人. 美食. 公司. 学校. 旅游. 电商. 宠物. 电器. 茶叶. 家居. 酒店. 舞蹈. 动漫. 明星. 服装. 体育. 化妆品. 物流. 环保. 书籍. 婚纱. 军 ...

  7. 嵌入式系统大作业——基于QT的3D模型展示

    嵌入式系统大作业--基于QT的3D模型展示 写在前面 实验设备 实现内容 实现过程 在win10上利用SolidWorks软件对模型进行预处理: 编写代码实现功能: 效果演示 参考资料 写在前面 该大 ...

  8. web网页设计实例作业 HTML5+CSS大作业——简单的个人图片网站(6页)

    HTML5+CSS大作业--简单的个人图片网站(6页) 常见网页设计作业题材有 个人. 美食. 公司. 学校. 旅游. 电商. 宠物. 电器. 茶叶. 家居. 酒店. 舞蹈. 动漫. 明星. 服装. ...

  9. HTML5期末考核大作业:美食主题网站设计——沪上美食(9页)带Flash动画视频导航下拉表单 HTML+CSS+JavaScript

    HTML5期末大作业:美食主题网站设计--沪上美食(9页)带Flash动画视频导航下拉表单 HTML+CSS+JavaScript 期末作业HTML代码 学生网页课程设计期末作业下载 web网页设计制 ...

最新文章

  1. css实现图片虚化_HTML+CSS入门 如何实现背景图片虚化效果
  2. 【数据库学习】——数据库可视化--Navicat下载安装连接教程
  3. java控制台高级_K9s Kubernetes的高级控制台
  4. python 输出文字_Python中输出ASCII大文字、艺术字、字符字小技巧
  5. android qq音乐api使用,QQ音乐API
  6. 著名的用户界面设计准则
  7. unable to remove repository reference  (must force) - container is using its referenced image
  8. 百战程序员python资源_Python【北京尚学堂·百战程序员】
  9. hdu 5211 Mutiple 数学
  10. js获取 本周,本月的日期
  11. Android系统Audio框架介绍
  12. 关于程序新手入行的分析与看法
  13. python十字坐标轴绘制_matplotlib画十字坐标图
  14. atlas mysql怎么用,MySQL —— Atlas 使用
  15. IE/Firefox每次刷新时自动检查网页更新,无需手动清空缓存的设置方法(转)
  16. C语言 深度探究C语言中的函数
  17. JAVA 实现MD5加密算法
  18. 酷炫的业务看板大屏可以使用 Python 轻松制作( 附完整代码)
  19. Linux触屏驱动Windows,linux 触摸屏驱动编写
  20. 书单|刀剑如梦,如何走好自己的江湖路?

热门文章

  1. 基础训练:龟兔赛跑预测
  2. 短视频查重机制及去重方法
  3. python打印电子标签--ghostscript 和reportlab实现
  4. 黄金圈理论和知识体系
  5. Task3:第三回:布局格式定方圆
  6. 2.6顺序表和链表的优缺点(区别、特点)详解
  7. 带空格直角三角形图案的输出-c++
  8. 微信小程序手机号码如何进行解密
  9. 追赶的腾讯云 | 深网
  10. 植物大战 类和对象 ——C++