此程序分成两部分,一部分是对图片进行处理,一部分是对视频进行处理,其余还有一些小功能!
目录
原理(代码在后面):
图片处理:
1)图片的打开
2)图片的切换
3)图片的灰度化
4)二值化的实现
5)均值滤波处理
6)伽马变换
7)边缘变换
视频处理:
代码:
OpenCV的使用
图片处理实现功能:对实现多张图片打开,并且可以切换当前操作的图片,实现对图片进行灰度化,二值化(阈值可调),进行均值滤波,伽马变换,边缘变化,恢复原图,亮度调节,实现对编辑后的图片进行保存。
视频处理实现功能:选择视频,对视频进行进度条控制,灰度化处理,边缘变换处理,控制视频大小,平滑处理,二值化处理,马赛克处理。
效果展示:
图片和视频是一个tabWidget,里面放了两个label,一个放图片,一个放视频。
图片打开可以选择多个或者一个,区别就是QFileDialog::getOpenFilenames()这里有s,这意味着多个打开就是取图片生成列表,但是单个打开就没有这个s了,只是一个对象
//多个图片打开
strlist= QFileDialog::getOpenFileNames(this,tr("选择文件"),"F:\\Qtfile\\homework\\images","图片文件(*png *jpg);;""所有文件(*.*)");
//单个图片打开
s=QFileDialog::getOpenFileName(this,"open file dialog", "F:\\Qtfile\\homework\\images","all files(*.*);;""pngfiles(*.png);;""jpgfiles(*.jpg)");
因为有多张图片,那么就需要切换编辑的对象,这个时候就需要用数组了,所以上面使用的是list,这个只需要设置切换的list[i]进行编辑了,请注意,小细节就是i=0与list.length别越界,最好设置一个提醒。
就是直接获取图片的每个像素点,然后对图片遍历的像素点获取它的RGB,也就是qRed,qGreen,qBlue三个值,然后取你的模板,我的是直接
int average = (qRed(line[x])+qGreen(line[x])+qBlue(line[x]))/3
模板随便取,无非就是qRed这三个参数前面的系数。
二值化就是取一个标准,与遍历后的每个像素点,如果像素点的qRed(这个随便,也可以是qGreen,qBlue)大于这个标准,就直接将像素点的RGB设置为255顶峰,如果小于就设置为0。我这里没有选择自适应二值化的阈值,而是选择了阈值可调节,用了一个spinBox来控制阈值的传输大小。
均值滤波就是遍历每一个像素点,然后选定一个模板,对这个像素点周围的点与它自身求RGB加权计算出一个数值,然后将这个数值赋予这个点。这里选定的模板是,就是取其上面一点,上面左边一点,上面右边一点,正右边一点,正左边一点,正下面一点,下面左边一点,下面右边一点,然后这九个点的RGB进行求和取均值在赋予这一点(注意第0行和第0列)
QImage *newImage = new QImage(img->width(),img->height(),QImage::Format_ARGB32); for(int y=2;y
for (int x=2;x
#处理代码}})
目的就是为了处理图片一些曝光不足或者曝光过度的像素点,可以采用不同的模板对每个不同的像素点进行处理,
double average = (qRed(line[x])+qGreen(line[x])+qBlue(line[x]))/3;
double red = pow(qRed(line[x])/255.0,gammacoe)*255;
double green = pow(qGreen(line[x])/255.0,gammacoe)*255;
double blue = pow(qBlue(line[x])/255.0,gammacoe)*255;
int averagechanged = pow(average/255,gammacoe)*255;
这个averchanged就是我这里的最终像素值。
使界面只能凸显图片边缘的像素点,非边缘点全部变为白色、,主要有三种处理的边缘算法,一种是梯度法边缘检测(一阶边缘检测算子),还有Roberts法边缘检测,Sobel法边缘检测
梯度法边缘检测:
QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32)
QColor color0;
QColor color1;
QColor color2;
int r = 0;
int g = 0;
int b = 0;
int rgb = 0;
int r1 = 0;
int g1 = 0;
int b1 = 0;
int rgb1 = 0;
int a = 0;
for( int y = 0; y < image->height() - 1; y++) {
for(int x = 0; x < image->width() - 1; x++)
{
color0 = QColor ( image->pixel(x,y));
color1 = QColor ( image->pixel(x + 1,y));
color2 = QColor ( image->pixel(x,y + 1));
r = abs(color0.red() - color1.red());
g = abs(color0.green() - color1.green());
b = abs(color0.blue() - color1.blue());
rgb = r + g + b;
r1 = abs(color0.red() - color2.red());
g1= abs(color0.green() - color2.green());
b1 = abs(color0.blue() - color2.blue());
rgb1 = r1 + g1 + b1;
a = rgb + rgb1;
a = a * scale;
a = a>255?255:a;
newImage->setPixel(x,y,qRgb(a,a,a));
}
}
return newImage;
Roberts法边缘检测:
QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32); QColor color0; QColor color1; QColor color2; QColor color3; int r = 0; int g = 0; int b = 0; int rgb = 0; int r1 = 0; int g1 = 0; int b1 = 0; int rgb1 = 0; int a = 0; for( int y = 0; y < image->height() - 1; y++) { for(int x = 0; x < image->width() - 1; x++) { color0 = QColor ( image->pixel(x,y)); color1 = QColor ( image->pixel(x + 1,y)); color2 = QColor ( image->pixel(x,y + 1)); color3 = QColor ( image->pixel(x + 1,y + 1)); r = abs(color0.red() - color3.red()); g = abs(color0.green() - color3.green()); b = abs(color0.blue() - color3.blue()); rgb = r + g + b; r1 = abs(color1.red() - color2.red()); g1= abs(color1.green() - color2.green()); b1 = abs(color1.blue() - color2.blue()); rgb1 = r1 + g1 + b1; a = rgb + rgb1; a = a * scale; a = a>255?255:a; newImage->setPixel(x,y,qRgb(a,a,a)); } } return newImage;
Sobel法边缘检测:
QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32); QColor color0; QColor color1; QColor color2; QColor color3; QColor color4; QColor color5; QColor color6; QColor color7; QColor color8; int r = 0; int g = 0; int b = 0; int rgb = 0; int r1 = 0; int g1 = 0; int b1 = 0; int rgb1 = 0; int a = 0; for( int y = 1; y < image->height() - 1; y++) { for(int x = 1; x < image->width() - 1; x++) { color0 = QColor ( image->pixel(x,y)); color1= QColor ( image->pixel(x-1,y-1)); color2 = QColor ( image->pixel(x,y-1)); color3 = QColor ( image->pixel(x+1,y)); color4 = QColor ( image->pixel(x-1,y)); color5 = QColor ( image->pixel(x+1,y)); color6 = QColor ( image->pixel(x-1,y+1)); color7= QColor ( image->pixel(x,y+1)); color8 = QColor ( image->pixel(x+1,y+1)); r = abs(color1.red() + color2.red() * 2 + color3.red() - color6.red() - color7.red() * 2 - color8.red()); g = abs(color1.green() + color2.green() * 2 + color3.green() - color6.green() - color7.green() * 2 - color8.green()); b = abs(color1.blue() + color2.blue() * 2 + color3.blue() - color6.blue() - color7.blue() * 2 - color8.blue()); rgb = r + g + b; r1 = abs(color1.red() + color4.red() * 2 + color6.red() - color3.red() - color5.red() * 2 - color8.red()); g1= abs(color1.green() + color4.green() * 2 + color6.green() - color3.green() - color5.green() * 2 - color8.green()); b1 = abs(color1.blue() + color4.blue() * 2 + color6.blue() - color3.blue() - color5.blue() * 2 - color8.blue()); rgb1 = r1 + g1 + b1; if(type == 0) { if (rgb > rgb1) a = rgb; else a = rgb1; } else if(type == 1) { a = (rgb + rgb1)/2; } a = a * scale; a = a>255?255:a; newImage->setPixel(x,y,qRgb(a,a,a)); } } return newImage;
8)亮度调节,就是遍历每个像素点,然后将每个像素点的RGB加上或者减去同一个数值,这个时候要注意一下RGB为0或者255的时候的越界。
9)恢复原图,直接获取图片路径重新放置在label中。
10)保存图片,获取label中的图片然后保存。
首先是获取视频的路径,然后将视频捕获,获取捕获的帧数,然后设置开始的帧数,获取帧率,然后启动timer的计时函数,一个一个的往下读取帧,如果暂停的话就不读取了。视频的灰度化,边缘处理,二值化,马赛克都是直接使用OpenCV里面的内部函数,也可以自己写,但是没有必要。OpenCV的下载安装在后面。其余比如视频的伽马变换,视频的亮度调节也是可以实现的,只要自己网上找还是有一大堆资源,只要视频OpenCv库,应该也没什么代码,有效代码不会超过二十行。
CPP代码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace cv;
QImage *img;
QImage a;
QString s;
static QTranslator* t = new QTranslator();
int b=50;//二值化指标
int index = 0;//打开多文件的初始值
QStringList strlist;
bool isstart=false;
QString origin_path;//目前处理的图片的原图
QString videoSrcDir;//视频路径
VideoCapture capture; //用来读取视频结构
QTimer timer;//视频播放的定时器
int beishu;//调节播放速率
int delay;//帧延迟时间
int sign=0;//视频操作类型
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setWindowTitle("199050835游天乐");
// this->setStyleSheet()
ui->label->setStyleSheet("QLabel{background-color:rgb(250,250,250);}");
//设置图片自适应
ui->label->setScaledContents(true);
connect(&timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
connect(&timer, SIGNAL(timeout()), this, SLOT(updatePosition()));
}
MainWindow::~MainWindow()
{
delete ui;
}
//文件打开
void MainWindow::on_action_O_triggered()
{
strlist= QFileDialog::getOpenFileNames(this,tr("选择文件"),"F:\\Qtfile\\homework\\images","图片文件(*png *jpg);;""所有文件(*.*)");
// s=QFileDialog::getOpenFileName(this,"open file dialog", "F:\\Qtfile\\homework\\images","all files(*.*);;""pngfiles(*.png);;""jpgfiles(*.jpg)");
if(strlist.length()==0){
QMessageBox::information(NULL,"提示","图片选择失败");
}else{
s = strlist[index];
if(s==NULL){
QMessageBox::information(NULL,"提示","图片选择失败");
}else{
a = QImage(s);
img = &a;
ui->label->setPixmap(QPixmap::fromImage(a));
}
}
}
//上一张按钮
void MainWindow::on_lastimg_clicked()
{
if(strlist.length()==0){
QMessageBox::information(NULL,"提示","选择文件为空");
}else{
if(index == 0){
QMessageBox::information(NULL,"提示","已是第一张图片");
}else{
index = index - 1;
s = strlist[index];
a = QImage(s);
img = &a;
ui->label->clear();
ui->label->setPixmap(QPixmap::fromImage(a));
}
}
}
//下一张图片
void MainWindow::on_nextimg_clicked()
{
if(strlist.length()==0){
QMessageBox::information(NULL,"提示","选择文件为空");
}else{
if(index == strlist.length()-1){
QMessageBox::information(NULL,"提示","已是最后一张图片");
}else{
index = index + 1;
s = strlist[index];
a = QImage(s);
img = &a;
ui->label->clear();
ui->label->setPixmap(QPixmap::fromImage(a));
}
}
}
//灰度化按钮
void MainWindow::on_grey_clicked()
{
if(s==NULL){
QMessageBox::information(NULL,"提示","图片选择失败");
}else{
img = greyScale(img);
QPixmap pix(QPixmap::fromImage(*img));//将图片转化为Qpixmap类型方便在label内部显示
ui->label->setPixmap(QPixmap(""));
ui->label->setPixmap(pix);
}
}
//二值化按钮 二值化就是将图像的像素点高于某个值x全部设置为255,低于x设置为0
void MainWindow::on_threshold_clicked()
{
if(s==NULL){
QMessageBox::information(NULL,"提示","图片选择失败");
}else{
img = Thresholding();
QPixmap pix(QPixmap::fromImage(*img));//将图片转化为Qpixmap类型方便在label内部显示
ui->label->clear();
ui->label->setPixmap(pix);
}
}
//均值滤波按钮
void MainWindow::on_average_clicked()
{
if(s==NULL){
QMessageBox::information(NULL,"提示","图片未选择!");
}else{
img = FilterMean(img);
QPixmap pix(QPixmap::fromImage(*img));//将图片转化为Qpixmap类型方便在label内部显示
ui->label->setPixmap(QPixmap(""));
ui->label->setPixmap(pix);
}
}
//伽马变换按钮
void MainWindow::on_gamma_clicked()
{
if(s==NULL){
QMessageBox::information(NULL,"提示","图片未选择!");
}else{
img = GammaTrans(img);
QPixmap pix(QPixmap::fromImage(*img));//将图片转化为Qpixmap类型方便在label内部显示
ui->label->setPixmap(QPixmap(""));
ui->label->setPixmap(pix);
}
}
//灰度化处理函数
QImage* MainWindow::greyScale(QImage *img)
{
for (int y = 0;yheight(); y++) {
//获取一行像素的首地址
QRgb *line = (QRgb *)img->scanLine(y);
for(int x=0;xwidth();x++){
//提取像素
int average = (qRed(line[x])+qGreen(line[x])+qBlue(line[x]))/3;
img->setPixel(x,y,qRgb(average,average,average));
}
}
return img;
}
//二值化处理函数
QImage* MainWindow::Thresholding()
{
a = QImage(s);
QPixmap pix(QPixmap::fromImage(*img));//将图片转化为Qpixmap类型方便在label内部显示
ui->label->clear();
ui->label->setPixmap(pix);
img = greyScale(img);
int standard = b;
for (int y = 0;yheight(); y++) {
//获取一行像素的首地址
QRgb *line = (QRgb *)img->scanLine(y);
for(int x=0;xwidth();x++){
//提取像素
int color;
if(qRed(line[x])>standard){
color = 255;
}else{
color = 0;
}
img->setPixel(x,y,qRgb(color,color,color));
}
}
return img;
}
//均值滤波处理函数
QImage* MainWindow::FilterMean(QImage *img)
{
QImage *newImage = new QImage(img->width(),img->height(),QImage::Format_ARGB32);
for(int y=2;yheight()-1;y++){
for (int x=2;xwidth()-1;x++) {
QRgb *line2 =(QRgb *)img->scanLine(y);
QRgb *line1=(QRgb *)img->scanLine(y-1);
QRgb *line3 =(QRgb *)img->scanLine(y+1);
int averageRed = (qRed(line1[x])+qRed(line2[x])+qRed(line3[x])+
qRed(line1[x-1])+qRed(line2[x-1])+qRed(line3[x-1])+
qRed(line1[x+1])+qRed(line2[x+1])+qRed(line3[x+1])
)/9;
int averageGreen = (qGreen(line1[x])+qGreen(line1[x])+qGreen(line1[x])+
qGreen(line1[x-1])+qGreen(line2[x-1])+qGreen(line3[x-1])+
qGreen(line1[x+1])+qGreen(line2[x+1])+qGreen(line3[x+1]))/9;
int averageBlue = (qBlue(line1[x])+qBlue(line1[x])+qBlue(line1[x])+
qBlue(line1[x-1])+qBlue(line2[x-1])+qBlue(line3[x-1])+
qBlue(line1[x+1])+qBlue(line2[x+1])+qBlue(line3[x+1]))/9;
newImage->setPixel(x,y,qRgb(averageRed,averageGreen,averageBlue));
}
}
img = newImage;
return img;
}
//伽马变换函数
QImage* MainWindow::GammaTrans(QImage *img)
{
double gammacoe = 0.5;
for (int y = 0;yheight(); y++) {
//获取一行像素的首地址
QRgb *line = (QRgb *)img->scanLine(y);
for(int x=0;xwidth();x++){
//提取像素
double average = (qRed(line[x])+qGreen(line[x])+qBlue(line[x]))/3;
double red = pow(qRed(line[x])/255.0,gammacoe)*255;
double green = pow(qGreen(line[x])/255.0,gammacoe)*255;
double blue = pow(qBlue(line[x])/255.0,gammacoe)*255;
int averagechanged = pow(average/255,gammacoe)*255;
img->setPixel(x,y,qRgb(red,green,blue));
}
}
return img;
}
//边缘检测按钮
void MainWindow::on_verge_clicked()
{
if(s==NULL){
QMessageBox::information(NULL,"提示","图片未选择!");
}else{
img = SideGrandiant(img,2.0);//梯度边缘;
QPixmap pix(QPixmap::fromImage(*img));//将图片转化为Qpixmap类型方便在label内部显示
ui->label->setPixmap(QPixmap(""));
ui->label->setPixmap(pix);
}
}
//边缘检测函数
QImage* MainWindow::SideGrandiant(QImage *img,double scale)
{
QImage* newImage = new QImage(img->width(),img->height(),QImage::Format_ARGB32);
QColor color0;
QColor color1;
QColor color2;
int r = 0;
int g = 0;
int b = 0;
int rgb = 0;
int r1 = 0;
int g1 = 0;
int b1 = 0;
int rgb1 = 0;
int a = 0;
for( int y = 0; y < img->height() - 1; y++){
for(int x = 0; x < img->width() - 1; x++){
color0 = QColor ( img->pixel(x,y));
color1 = QColor ( img->pixel(x + 1,y));
color2 = QColor ( img->pixel(x,y + 1));
r = abs(color0.red() - color1.red());
g = abs(color0.green() - color1.green());
b = abs(color0.blue() - color1.blue());
rgb = r + g + b;
r1 = abs(color0.red() - color2.red());
g1= abs(color0.green() - color2.green());
b1 = abs(color0.blue() - color2.blue());
rgb1 = r1 + g1 + b1;
a = rgb + rgb1;
a = a * scale;
a = a>255?255:a;
newImage->setPixel(x,y,qRgb(a,a,a));
}
}
return newImage;
}
//图片变亮按钮
void MainWindow::on_uplight_clicked()
{
if(s== NULL){
QMessageBox::information(NULL,"提示","图片为空!");
}else{
img = UpLightness(img);
QPixmap pix(QPixmap::fromImage(*img));//将图片转化为Qpixmap类型方便在label内部显示
ui->label->setPixmap(QPixmap(""));
ui->label->setPixmap(pix);
}
}
//亮度下调按钮
void MainWindow::on_downlight_clicked()
{
if(s== NULL){
QMessageBox::information(NULL,"提示","图片为空!");
}else{
img = DownLightness(img);
QPixmap pix(QPixmap::fromImage(*img));//将图片转化为Qpixmap类型方便在label内部显示
ui->label->setPixmap(QPixmap(""));
ui->label->setPixmap(pix);
}
}
//图片变亮函数
QImage* MainWindow::UpLightness(QImage *img){
int value = 5;
for (int y = 0;yheight(); y++) {
//获取一行像素的首地址
QRgb *line = (QRgb *)img->scanLine(y);
for(int x=0;xwidth();x++){
//提取像素
unsigned int red,green,blue;
if(qRed(line[x])+value<255){
red = qRed(line[x])+value;
}else{
red = 254;
QMessageBox::information(NULL,"提示","亮度上调至极限!");
ui->uplight->setEnabled(false);
}
if(qGreen(line[x])+value<255){
green = qGreen(line[x])+value;
}else{
green = 255;
QMessageBox::information(NULL,"提示","亮度上调至极限!");
ui->uplight->setEnabled(false);
}
if(qBlue(line[x])+value<255){
blue = qBlue(line[x])+value;
}else{
blue = 255;
QMessageBox::information(NULL,"提示","亮度上调至极限!");
ui->uplight->setEnabled(false);
}
img->setPixel(x,y,qRgb(red,green,blue));
}
}
return img;
}
//亮度下调函数
QImage* MainWindow::DownLightness(QImage *img)
{
ui->uplight->setEnabled(true);
int value = 5;
for (int y = 0;yheight(); y++) {
//获取一行像素的首地址
QRgb *line = (QRgb *)img->scanLine(y);
for(int x=0;xwidth();x++){
//提取像素
unsigned int red,green,blue;
if(qRed(line[x])-value>0){
red = qRed(line[x])-value;
}else{
red = 0;
/*QMessageBox::information(NULL,"提示","亮度下调至极限!");
ui->uplight->setEnabled(false);*/
}
if(qGreen(line[x])-value>0){
green = qGreen(line[x])-value;
}else{
green = 0;
}
if(qBlue(line[x])-value>0){
blue = qBlue(line[x])-value;
}else{
blue = 0;
}
img->setPixel(x,y,qRgb(red,green,blue));
}
}
return img;
}
void MainWindow::on_saveimg_clicked()
{
if(s== NULL){
QMessageBox::information(NULL,"提示","图片为空!");
}else{
QString filename1 = QFileDialog::getSaveFileName(this,tr("Save Image"),"F:\\Qtfile\\ytl5\\images",tr("Images (*.png *.bmp *.jpg)")); //选择路径
QScreen *screen = QGuiApplication::primaryScreen();
screen->grabWindow(ui->label->winId()).save(filename1);
}
}
void MainWindow::on_action_S_triggered()
{
if(s== NULL){
QMessageBox::information(NULL,"提示","图片为空!");
}else{
QString filename1 = QFileDialog::getSaveFileName(this,tr("Save Image"),"F:\\Qtfile\\ytl5\\images",tr("Images (*.png *.bmp *.jpg)")); //选择路径
QScreen *screen = QGuiApplication::primaryScreen();
screen->grabWindow(ui->label->winId()).save(filename1);
}
}
void MainWindow::on_action_E_triggered()
{
t->load(":/pre/En.qm");
qApp->installTranslator(t);
ui->retranslateUi(this);
}
void MainWindow::on_action_C_2_triggered()
{
qApp->removeTranslator(t);
ui->retranslateUi(this);
}
//二值化spinBox值改变
void MainWindow::on_spinBox_valueChanged(int arg1)
{
qDebug()<label->setPixmap(QPixmap::fromImage(a));
}
}
void MainWindow::on_action_N_triggered()
{
QImage newpro = QImage(600,500,QImage::Format_RGB32);
QColor color = qRgb(255,255,255);
newpro.fill(color);
QPixmap pix(QPixmap::fromImage(newpro));//将图片转化为Qpixmap类型方便在label内部显示
ui->label->setPixmap(QPixmap(""));
ui->label->setPixmap(pix);
}
void MainWindow::on_action_Qt_A_triggered()
{
QMessageBox::information(NULL,"关于","本软件制作用于图片处理");
}
//视频选择按钮
void MainWindow::on_vedioselect_clicked()
{
QString video_path = QFileDialog::getOpenFileName(this,tr("选择视频"),"F:\\Qtfile\\homework\\images",tr("Video (*.WMV *.mp4 *.rmvb *.flv)"));
if(video_path!=nullptr){
//打开视频文件:其实就是建立一个VideoCapture结构
capture.open(video_path.toStdString());
//检测是否正常打开:成功打开时,isOpened返回ture
if (!capture.isOpened())
QMessageBox::warning(nullptr, "提示", "打开视频失败!", QMessageBox::Yes | QMessageBox::Yes);
ui->tabWidget->setCurrentIndex(1);
// ui->Btn_play->setEnabled(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);
sign=0;
//timer.start();
isstart=!isstart;
}
}
//进度条随视频移动
void MainWindow::updatePosition(){
long totalFrameNumber = capture.get(CAP_PROP_FRAME_COUNT);
ui->horizontalSlider->setMaximum(totalFrameNumber);
long frame=capture.get(CAP_PROP_POS_FRAMES );
ui->horizontalSlider->setValue(frame);
}
//进度条拖动
void MainWindow::on_horizontalSlider_valueChanged(int value)
{
capture.set(CAP_PROP_POS_FRAMES, value);
}
//秒转分函数
QString MainWindow::stom(int s){
QString m;
if(s/60==0){
m=QString::number (s%60);
}else{
m=QString::number (s/60)+":"+QString::number (s%60);
}
return m;
}
//timer触发函数
void MainWindow::onTimeout()
{
Mat frame;
//读取下一帧
double rate = capture.get(CAP_PROP_FPS);
double nowframe=capture.get(CAP_PROP_POS_FRAMES );
int nows=nowframe/rate;
long totalFrameNumber = capture.get(CAP_PROP_FRAME_COUNT);
int totals=totalFrameNumber/rate;
ui->label_3->setText(stom(nows)+"/"+stom(totals));
if (!capture.read(frame))
{
return;
}
if(sign==1){
cvtColor(frame,frame,6);
}
else if(sign==2){
cvtColor(frame, frame,6);
//边缘检测
//Canny检测
int edgeThresh =100;
Mat Canny_result;
Canny(frame, frame, edgeThresh, edgeThresh * 3, 3);
}else if(sign==3)
{
//滤波
GaussianBlur(frame, frame, Size(3, 3), 0, 0);
}
else if(sign==4){
//边缘化
cvtColor(frame,frame,6);
threshold(frame, frame, 96, 255, THRESH_BINARY);
}else if (sign==5) {
//马赛克
frame=masaike(frame);
}
QImage image=MatToQImage(frame);
double scale=ui->verticalSlider->value()/100.0;
QSize qs = ui->label_2->rect().size()*scale;
ui->label_2->setPixmap(QPixmap::fromImage(image).scaled(qs));
ui->label_2->setAlignment(Qt::AlignCenter);
ui->label_2->repaint();
}
//Mat转图像
QImage MainWindow::MatToQImage(const cv::Mat& mat)
{
// 8-bits unsigned, NO. OF CHANNELS = 1
if (mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
// Set the color table (used to translate colour indexes to qRgb values)
image.setColorCount(256);
for (int i = 0; i < 256; i++)
{
image.setColor(i, qRgb(i, i, i));
}
// Copy input Mat
uchar *pSrc = mat.data;
for (int row = 0; row < mat.rows; row++)
{
uchar *pDest = image.scanLine(row);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return image;
}
// 8-bits unsigned, NO. OF CHANNELS = 3
else if (mat.type() == CV_8UC3)
{
// Copy input Mat
const uchar *pSrc = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
else if (mat.type() == CV_8UC4)
{
// Copy input Mat
const uchar *pSrc = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
else
{
return QImage();
}
}
//暂停/播放
void MainWindow::on_stopplay_clicked()
{
if(isstart)
{
timer.stop();
isstart=false;
}else {
timer.start(delay);
isstart=true;
}
}
//局部马赛克函数调用
Mat MainWindow::masaike(Mat src){
int width = src.rows; //图片的长度
int height = src.cols; //图片的宽度
//10*10的像素点进行填充
int arr = 10;
//i和j代表了矩形区域的左上角的像素坐标
for (int i = width/2.5; i < width/1.5; i+=arr) {
for (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++) {
//在这里进行颜色的修改
src.at(k, m)[0] = src.at(i, j)[0];
src.at(k, m)[1] = src.at(i, j)[1];
src.at(k, m)[2] = src.at(i, j)[2];
}
}
}
}
return src;
}
//灰度化
void MainWindow::on_greyvideo_clicked()
{
sign=1;
}
//边缘化
void MainWindow::on_sobevideo_clicked()
{
sign = 2;
}
//滤波处理
void MainWindow::on_gaosivideo_clicked()
{
sign = 3;
}
//二值化
void MainWindow::on_distinctvideo_clicked()
{
sign = 4;
}
//马赛克
void MainWindow::on_masaikevideo_clicked()
{
sign = 5;
}
————————————————————————————————————————
//.H代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_action_O_triggered();
void on_grey_clicked();
QImage* greyScale(QImage *image);
void on_threshold_clicked();
QImage* Thresholding();
void on_average_clicked();
QImage* FilterMean(QImage *image);
void on_gamma_clicked();
QImage* GammaTrans(QImage *image);
void on_verge_clicked();
QImage* SideGrandiant(QImage *image,double scale);
void on_action_E_triggered();
void on_action_C_2_triggered();
void on_spinBox_valueChanged(int arg1);
void on_uplight_clicked();
void on_downlight_clicked();
void on_saveimg_clicked();
QImage *UpLightness(QImage *img);
QImage *DownLightness(QImage *img);
//视频
void on_restart_clicked();
void on_action_N_triggered();
void on_action_Qt_A_triggered();
void on_vedioselect_clicked();
// void on_startplay_clicked();
void on_lastimg_clicked();
void on_nextimg_clicked();
void onTimeout();
QImage MatToQImage(const cv::Mat& mat);
QString stom(int s);
void on_horizontalSlider_valueChanged(int value);
void updatePosition();
void on_stopplay_clicked();
void on_greyvideo_clicked();
void on_gaosivideo_clicked();
void on_distinctvideo_clicked();
void on_masaikevideo_clicked();
cv::Mat masaike(cv::Mat image);
void on_sobevideo_clicked();
void on_action_S_triggered();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
有关OpenCV的事儿:OpenCV可以理解为是Qt的一个代码库,如果要安装OpenCV,其实挺不容易的,首先你得安装Cmask,然后下载OpenCV,这是一个压缩包,来源于国外,国内也有,国外的下载比较慢,所以要安装的话建议不要去下载国外的(当然你也可以下载),下载国外的官网的需要大约几个小时;然而下载国内的话,你得自己找资源,清华大学和上海交通大学好像是有资源的。下载完之后还得配置电脑环境重启电脑,然后再用Cmask解析安装OpenCV........
于是,说了这么多,网上还是有很多教程的,建议你按照教程来,有些电脑会报错,是因为环境问题,众所周知,环境问题可多了,你也可以直接网上找解决方案,也可以暴力重装系统......
OpenCV其实是可以直接拿资源包就是能用的那个下载下来随便放置一个目录下,然后用OpenCV来使用,你可以看网上的教程https://blog.csdn.net/weixin_43763292/article/details/112975207
拿着我的安装包(我的是64位的,如果你的不是的话就得另外找资源了)直接跳到这里进行后面的操作,注意这个放置的位置哟!
注意,不到万不得已不要自己配,因为失败率还是挺高的
OpenCV压缩包链接:
链接:https://pan.baidu.com/s/1AA_Zvm_9nSrBrVddhVxptQ
提取码:o1ho
如有其他需求,可以邮箱[email protected],这也是QQ号哟!