图像处理之qt实现
2015-08-11 09:34
483 查看
作为图像处理的入门,会文件操作,能顺利得到图像的像素就足够了。但是在这方面做出成就就很难了,因为它涉及了很多算法,要做的出众就要有一定的创新就很难了。像海康这样做安防的,在视频方面做得之所以出众,就是因为他们在图像处理、画面处理方面的算法都有自己的创新。
下面是这段时间,我关于图像处理方面的一些入门算法的实现代码,使用qt实现的,为自己后期实现图像处理(如:图像变形、分割等)做准备,代码分享如下:
点击(此处)折叠或打开
#include \"mainwindow.h\"
#include \"ui_mainwindow.h\"
#include <QFileDialog>
#include <QMovie>
#include <QRgb>
#include <math.h>
#include <QInputDialog>
#include <QDebug>
#include <QDialog>
#include <QDoubleSpinBox>
#include <QSpinBox>
#include <QLabel>
MainWindow::MainWindow(QWidget
*parent)
:
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QMenu *editMenu=ui->menuBar->addMenu(QObject::tr(\"图片(&P)\"));
QAction *action_Open=editMenu->addAction(QObject::tr(\"打开图片&O\"));
QMenu *editMenuMake=ui->menuBar->addMenu(QObject::tr(\"图像几何变换(&M)\"));
QAction *action_Make1=editMenuMake->addAction(QObject::tr(\"图像平移(&T)\"));
QAction *action_Make2=editMenuMake->addAction(QObject::tr(\"图像放缩(&S)\"));
QMenu *editMenuBetter=ui->menuBar->addMenu(QObject::tr(\"图像增强(&B)\"));
QAction *action_Better1=editMenuBetter->addAction(QObject::tr(\"图像锐化(&E)\"));
QAction *action_Better2=editMenuBetter->addAction(QObject::tr(\"直方图均衡化(&A)\"));
QAction *action_Better3=editMenuBetter->addAction(QObject::tr(\"消除噪声(&D)\"));
QMenu *editMenuTiqu=ui->menuBar->addMenu(QObject::tr(\"提取(&G)\"));
QAction *action_Gray=editMenuTiqu->addAction(QObject::tr(\"图像灰度化\"));
QAction *action_Get1=editMenuTiqu->addAction(QObject::tr(\"Sobel算子提取\"));
action_Open->setCheckable(true);
action_Make1->setCheckable(true);
action_Make2->setCheckable(true);
action_Better1->setCheckable(true);
action_Better2->setCheckable(true);
action_Better3->setCheckable(true);
action_Gray->setCheckable(true);
action_Get1->setCheckable(true);
connect(action_Open,SIGNAL(triggered()),this,SLOT(OpenPicture()));
connect(action_Make1,SIGNAL(triggered()),this,SLOT(SetChangeValue()));
connect(action_Make2,SIGNAL(triggered()),this,SLOT(SetSouValue()));
connect(action_Better1,SIGNAL(triggered()),this,SLOT(SetBetterValue()));
connect(action_Better2,SIGNAL(triggered()),this,SLOT(MakePicAverage()));
connect(action_Gray,SIGNAL(triggered()),this,SLOT(RgbToGray()));
connect(action_Get1,SIGNAL(triggered()),this,SLOT(SobelGet()));
connect(action_Better3,SIGNAL(triggered()),this,SLOT(SelectYanKind()));
}
MainWindow::~MainWindow()
{
delete ui;
}
//获取要处理的图像并显示出来
void MainWindow::OpenPicture()
{
fileName=QFileDialog::getOpenFileName( this,tr(\"打开文件\"),\"/usr/local/Trolltech\",
tr(\"任何文件(*.*)\"\";;文本文件(*.txt)\"\";;XML文件(*.xml)\"\";;Images
(*.png *.xpm *.jpg)\"));
QMovie *move=new QMovie(fileName);
ui->label->move(50,100);
ui->label->setMovie(move);
move->start();
}
//确定图像左右、上下的平移量,并触发平移函数
void MainWindow::SetChangeValue()
{
dialog=new QDialog(this);
QLabel *WidthLabel=new QLabel(dialog);
WidthLabel->move(30,50);
WidthLabel->setText(tr(\"设置宽度的平移量\"));
setWidthChange=new QSpinBox(dialog);
setWidthChange->setMaximum(20);
setWidthChange->setMinimum(-20);
setWidthChange->move(180,50);
QLabel *HeightLabel=new QLabel(dialog);
HeightLabel->move(30,80);
HeightLabel->setText(tr(\"设置高度的平移量\"));
setHeightChange=new QSpinBox(dialog);
setHeightChange->setMaximum(20);
setHeightChange->setMinimum(-20);
setHeightChange->move(180,80);
QPushButton *button=new QPushButton(dialog);
button->move(180,120);
button->setText(tr(\"确定\"));
dialog->show();
connect(button,SIGNAL(clicked()),this,SLOT(ShowChangePic()));
}
//平移函数
void MainWindow::ShowChangePic()
{
image=new QImage(fileName);
QImage ChangeImage;
ChangeImage=QImage(image->width(),image->height(),QImage::Format_ARGB32);
QRgb rgb;
int width,height;
int i,j;
int widthOffset,heightOffset;
width=image->width();
height=image->height();
widthOffset=setWidthChange->value();
heightOffset=setHeightChange->value();
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
rgb=image->pixel(i,j);
if(ChangeImage.valid(i+widthOffset,j+heightOffset))
{
ChangeImage.setPixel(i+widthOffset,j+heightOffset,rgb);
}
}
}
ui->label_2->resize(ChangeImage.width(),ChangeImage.height());
ui->label_2->setPixmap(QPixmap::fromImage(ChangeImage));
delete image;
delete dialog;
}
//设置图像伸缩的比例并触发伸缩函数
void MainWindow::SetSouValue()
{
dialog=new QDialog(this);
QLabel *WidthLabel=new QLabel(dialog);
WidthLabel->move(30,50);
WidthLabel->setText(tr(\"设置宽度的缩放比例\"));
setWidthBi=new QDoubleSpinBox(dialog);
setWidthBi->setMaximum(20);
setWidthBi->setMinimum(0.1);
setWidthBi->move(180,50);
QLabel *HeightLabel=new QLabel(dialog);
HeightLabel->move(30,80);
HeightLabel->setText(tr(\"设置高度的缩放比例\"));
setHeightBi=new QDoubleSpinBox(dialog);
setHeightBi->setMaximum(20);
setHeightBi->setMinimum(0.1);
setHeightBi->move(180,80);
QPushButton *button=new QPushButton(dialog);
button->move(180,120);
button->setText(tr(\"确定\"));
dialog->show();
connect(button,SIGNAL(clicked()),this,SLOT(ShowSouPic()));
}
//伸缩函数
void MainWindow::ShowSouPic()
{
int width,height;
image=new QImage(fileName);
width=image->width();
height=image->height();
double x,y,r1,r2,g1,g2,b1,b2;
int i,j;
double width_bi,height_bi;
QRgb rgb00,rgb01,rgb10,rgb11;
int r,g,b;
QImage SouImage;
width_bi=setWidthBi->value();
height_bi=setHeightBi->value();
SouImage=QImage(width*width_bi,height*height_bi,QImage::Format_ARGB32);
for(i=0;i<width*width_bi;i++)
{
for(j=0;j<height*height_bi;j++)
{
x=i*(1/width_bi);
y=j*(1/height_bi);
//边界采用单线性插值
if(ceil(x)==0&&ceil(y)!=0)
{
rgb00=image->pixel(0,ceil(y)-1);
rgb01=image->pixel(0,ceil(y));
r=(ceil(y)-y)*qRed(rgb00)+(y-(ceil(y)-1))*qRed(rgb01);
g=(ceil(y)-y)*qGreen(rgb00)+(y-(ceil(y)-1))*qGreen(rgb01);
b=(ceil(y)-y)*qBlue(rgb00)+(y-(ceil(y)-1))*qBlue(rgb01);
SouImage.setPixel(i,j,qRgb(r,g,b));
}
if(ceil(y)==0&&ceil(y)!=0)
{
rgb00=image->pixel(ceil(x)-1,0);
rgb10=image->pixel(ceil(x),0);
r=(ceil(x)-x)*qRed(rgb00)+(x-(ceil(x)-1))*qRed(rgb10);
g=(ceil(x)-x)*qGreen(rgb00)+(x-(ceil(x)-1))*qGreen(rgb10);
b=(ceil(x)-x)*qBlue(rgb00)+(x-(ceil(x)-1))*qBlue(rgb10);
SouImage.setPixel(i,j,qRgb(r,g,b));
}
//(0,0)点特殊处理
if(ceil(y)==0&&ceil(y)==0)
{
rgb00=image->pixel(0,0);
SouImage.setPixel(i,j,rgb00);
}
//非边界采用双线性插值
if(ceil(x)!=0&&ceil(y)!=0)
{
rgb00=image->pixel(ceil(x)-1,ceil(y)-1);
rgb01=image->pixel(ceil(x)-1,ceil(y));
rgb10=image->pixel(ceil(x),ceil(y)-1);
rgb11=image->pixel(ceil(x),ceil(y));
r1=(ceil(x)-x)*qRed(rgb00)+(x-(ceil(x)-1))*qRed(rgb10);
r2=(ceil(x)-x)*qRed(rgb01)+(x-(ceil(x)-1))*qRed(rgb11);
r=(int)((ceil(y)-y)*r1+(y-(ceil(y)-1))*r2);
g1=(ceil(x)-x)*qGreen(rgb00)+(x-(ceil(x)-1))*qGreen(rgb10);
g2=(ceil(x)-x)*qGreen(rgb01)+(x-(ceil(x)-1))*qGreen(rgb11);
g=(int)((ceil(y)-y)*g1+(y-(ceil(y)-1))*g2);
b1=(ceil(x)-x)*qBlue(rgb00)+(x-(ceil(x)-1))*qBlue(rgb10);
b2=(ceil(x)-x)*qBlue(rgb01)+(x-(ceil(x)-1))*qBlue(rgb11);
b=(int)((ceil(y)-y)*b1+(y-(ceil(y)-1))*b2);
SouImage.setPixel(i,j,qRgb(r,g,b));
}
}
}
ui->label_2->resize(SouImage.width(),SouImage.height());
ui->label_2->setPixmap(QPixmap::fromImage(SouImage));
delete image;
delete dialog;
}
//设置图像锐化的阈值并触发图像锐化函数
void MainWindow::SetBetterValue()
{
dialog=new QDialog(this);
QLabel *WidthLabel=new QLabel(dialog);
WidthLabel->move(30,50);
WidthLabel->setText(tr(\"设置锐化的阈值\"));
setBetterValue=new QSpinBox(dialog);
setBetterValue->setMaximum(100);
setBetterValue->setMinimum(10);
setBetterValue->move(180,50);
QPushButton *button=new QPushButton(dialog);
button->move(180,70);
button->setText(tr(\"确定\"));
dialog->show();
connect(button,SIGNAL(clicked()),this,SLOT(MakePicBetter()));
}
//图像锐化
void MainWindow::MakePicBetter()
{
image=new QImage(fileName);
QImage ImageBetter;
ImageBetter=QImage(image->width(),image->height(),QImage::Format_ARGB32);
int i,j;
int r,g,b,tmpR,tmpG,tmpB;
QRgb rgb00,rgb01,rgb10;
int width=image->width(),height=image->height();
int betterValue=setBetterValue->value();
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
if(image->valid(i,j)&&image->valid(i+1,j)&&image->valid(i,j+1))
{
rgb00=image->pixel(i,j);
rgb01=image->pixel(i,j+1);
rgb10=image->pixel(i+1,j);
r=qRed(rgb00);
g=qGreen(rgb00);
b=qBlue(rgb00);
tmpR=abs(qRed(rgb00)-qRed(rgb01))+abs(qRed(rgb00)-qRed(rgb10));
tmpG=abs(qGreen(rgb00)-qGreen(rgb01))+abs(qGreen(rgb00)-qGreen(rgb10));
tmpB=abs(qBlue(rgb00)-qBlue(rgb01))+abs(qBlue(rgb00)-qBlue(rgb10));
if((tmpR+120)<255)
{
if(tmpR>betterValue)
{
r=tmpR+120;
}
}
else
{
r=255;
}
if((tmpG+120)<255)
{
if(tmpG>betterValue)
{
g=tmpG+120;
}
}
else
{
g=255;
}
if((tmpB+120)<255)
{
if(tmpB>betterValue)
{
b=tmpB+120;
}
}
else
{
b=255;
}
ImageBetter.setPixel(i,j,qRgb(r,g,b));
}
}
}
ui->label_2->resize(ImageBetter.width(),ImageBetter.height());
ui->label_2->setPixmap(QPixmap::fromImage(ImageBetter));
delete image;
delete dialog;
}
//图像的直方图均衡化
void MainWindow::MakePicAverage()
{
image=new QImage(fileName);
QImage ImageAverage;
ImageAverage=QImage(image->width(),image->height(),QImage::Format_ARGB32);
int i,j;
int width,height;
width=image->width();
height=image->height();
QRgb rgb;
int r[256],g[256],b[256];//原图各个灰度数量的统计
int rtmp,gtmp,btmp,rj,gj,bj;
float rPro[256],gPro[256],bPro[256];//原图各个灰度级的概率
float rTemp[256],gTemp[256],bTemp[256];//均衡化后各个灰度级的概率
int rJun[256],gJun[256],bJun[256];//均衡化后对应像素的值
memset(r,0,sizeof(r));
memset(g,0,sizeof(g));
memset(b,0,sizeof(b));
//获取原图各个灰度的数量
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
rgb=image->pixel(i,j);
r[qRed(rgb)]++;
g[qGreen(rgb)]++;
b[qBlue(rgb)]++;
}
}
//获取原图各个灰度级的概率
for(i=0;i<256;i++)
{
rPro[i]=(r[i]*1.0)/(width*height);
gPro[i]=(g[i]*1.0)/(width*height);
bPro[i]=(b[i]*1.0)/(width*height);
}
//均衡化后各个灰度级的概率,同时获取均衡化后对应像素的值
for(i=0;i<256;i++)
{
if(i==0)
{
rTemp[0]=rPro[0];
gTemp[0]=gPro[0];
bTemp[0]=bPro[0];
}
else
{
rTemp[i]=rTemp[i-1]+rPro[i];
gTemp[i]=gTemp[i-1]+gPro[i];
bTemp[i]=bTemp[i-1]+bPro[i];
}
rJun[i]=(int)(255*rTemp[i]+0.5);
gJun[i]=(int)(255*gTemp[i]+0.5);
bJun[i]=(int)(255*bTemp[i]+0.5);
}
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
rgb=image->pixel(i,j);
rtmp=qRed(rgb);
gtmp=qGreen(rgb);
btmp=qBlue(rgb);
rj=rJun[rtmp];
gj=gJun[gtmp];
bj=bJun[btmp];
ImageAverage.setPixel(i,j,qRgb(rj,gj,bj));
}
}
ui->label_2->resize(ImageAverage.width(),ImageAverage.height());
ui->label_2->setPixmap(QPixmap::fromImage(ImageAverage));
delete image;
}
//Sobel算子提取图像边界
void MainWindow::SobelGet()
{
image=new QImage(fileName);
QImage SobelIma;
SobelIma=QImage(image->width(),image->height(),QImage::Format_ARGB32);
Template(SobelIma);
ui->label_2->resize(SobelIma.width(),SobelIma.height());
ui->label_2->setPixmap(QPixmap::fromImage(SobelIma));
}
//与算子进行卷积的函数
void MainWindow::Template(QImage
&SobelImage)
{
int width=image->width(),height=image->height();
int pixelNum=width*height;
int i,j,k,l;
float rResult,gResult,bResult;
float sobel1[9]={1,2,1,0,0,0,-1,-2,-1},sobel2[9]={1,0,-1,2,0,-2,1,0,-1};
QRgb pixelOld[pixelNum],pixelTemp1[pixelNum],pixelTemp2[pixelNum];
int rtmp,gtmp,btmp;
memset(pixelTemp1,255,pixelNum);
memset(pixelTemp2,255,pixelNum);
QRgb tmpRgb;
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
tmpRgb=image->pixel(i,j);
pixelOld[j*width+i]=tmpRgb;
}
}
for(j=1;j<height-1;j++)
{
for(i=1;i<width-1;i++)
{
rResult=0;
gResult=0;
bResult=0;
for(k=0;k<3;k++)
{
for(l=0;l<3;l++)
{
rResult+=qRed(pixelOld[(j-1+k)*width+(i-1+l)])*sobel1[k*3+l];
gResult+=qGreen(pixelOld[(j-1+k)*width+(i-1+l)])*sobel1[k*3+l];
bResult+=qBlue(pixelOld[(j-1+k)*width+(i-1+l)])*sobel1[k*3+l];
}
}
rResult=(float)fabs(rResult);
gResult=(float)fabs(gResult);
bResult=(float)fabs(bResult);
if(rResult>255)
{
rtmp=255;
}
else
rtmp=(int)(rResult+0.5);
if(gResult>255)
gtmp=255;
else
gtmp=(int)(gResult+0.5);
if(bResult>255)
btmp=255;
else
btmp=(int)(bResult+0.5);
pixelTemp1[j*width+i]=qRgb(rtmp,gtmp,btmp);
}
}
for(j=1;j<height-1;j++)
{
for(i=1;i<width-1;i++)
{
rResult=0;
gResult=0;
bResult=0;
for(k=0;k<3;k++)
{
for(l=0;l<3;l++)
{
rResult+=qRed(pixelOld[(j-1+k)*width+(i-1+l)])*sobel2[k*3+l];
gResult+=qGreen(pixelOld[(j-1+k)*width+(i-1+l)])*sobel2[k*3+l];
bResult+=qBlue(pixelOld[(j-1+k)*width+(i-1+l)])*sobel2[k*3+l];
}
}
rResult=(float)fabs(rResult);
gResult=(float)fabs(gResult);
bResult=(float)fabs(bResult);
if(rResult>255)
rtmp=255;
else
rtmp=(int)(rResult+0.5);
if(gResult>255)
gtmp=255;
else
gtmp=(int)(gResult+0.5);
if(bResult>255)
btmp=255;
else
btmp=(int)(bResult+0.5);
pixelTemp2[j*width+i]=qRgb(rtmp,gtmp,btmp);
}
}
for(i=0;i<pixelNum;i++)
{
if(pixelTemp2[i]>pixelTemp1[i])
pixelTemp1[i]=pixelTemp2[i];
}
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
SobelImage.setPixel(i,j,pixelTemp1[j*width+i]);
}
}
delete[] pixelTemp1;
delete[] pixelTemp2;
delete image;
}
//设置图像平滑的方法
void MainWindow::SelectYanKind()
{
dialog=new QDialog(this);
QLabel *Label=new QLabel(dialog);
Label->move(45,20);
Label->setText(tr(\"设置图像平滑的方法\"));
QLabel *DescLabel=new QLabel(dialog);
DescLabel->move(60,45);
DescLabel->setText(tr(\" 1--邻域平均法\\n 2--加权平均法\\n
3--选择式掩膜平滑\\n\"));
setKind=new QSpinBox(dialog);
setKind->setMaximum(3);
setKind->setMinimum(1);
setKind->move(65,100);
QPushButton *button=new QPushButton(dialog);
button->move(65,130);
button->setText(tr(\"确定\"));
dialog->show();
connect(button,SIGNAL(clicked()),this,SLOT(DecreseVoice()));
}
//将图像的像素信息存在缓存中,并通过调用图像平滑函数更改缓存中的信息
void MainWindow::DecreseVoice()
{
image=new QImage(fileName);
int i,j,k,num;
int width=image->width(),height=image->height();
QImage MoreClear;
MoreClear=QImage(width,height,QImage::Format_ARGB32);
num=width*height;
QRgb tmpPixel[num];
int yanKind=setKind->value();
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
k=i*height+j;
tmpPixel[k]=image->pixel(i,j);
}
}
MoreClearPic(tmpPixel,yanKind,width,height);
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
k=i*height+j;
MoreClear.setPixel(i,j,tmpPixel[k]);
}
}
ui->label_2->resize(width,height);
ui->label_2->setPixmap(QPixmap::fromImage(MoreClear));
delete dialog;
}
//,图形平滑函数,它通过调用相应的平滑化函数实现图像的不同平滑化
void MainWindow::MoreClearPic(QRgb
*tmpPixel,int yanKind,int width,int
height)
{
int i,j,k;
int num=width*height;
int rtmpPixel[num],gtmpPixel[num],btmpPixel[num];
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
k=i*height+j;
rtmpPixel[k]=qRed(tmpPixel[k]);
gtmpPixel[k]=qGreen(tmpPixel[k]);
btmpPixel[k]=qBlue(tmpPixel[k]);
}
}
if(yanKind==1)
{
YanMo1(rtmpPixel,width,height);
YanMo1(gtmpPixel,width,height);
YanMo1(btmpPixel,width,height);
}
if(yanKind==2)
{
YanMo2(rtmpPixel,width,height);
YanMo2(gtmpPixel,width,height);
YanMo2(btmpPixel,width,height);
}
/*if(yanKind==3)
{
YanMo3(rtmpPixel,width,height);
YanMo3(gtmpPixel,width,height);
YanMo3(btmpPixel,width,height);
}*/
for(i=1;i<width-1;i++)
{
for(j=1;j<height-1;j++)
{
k=i*height+j;
tmpPixel[k]=qRgb(rtmpPixel[k],gtmpPixel[k],btmpPixel[k]);
}
}
}
//邻域平均法平滑化函数
void MainWindow::YanMo1(int
*tmpPixel,
int width,
int height)
{
float Template[9]={1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9};
int i,j;
for(i=1;i<width-1;i++)
{
for(j=1;j<height-1;j++)
{
tmpPixel[i*height+j]=tmpPixel[(i-1)*height+j-1]*Template[0]+tmpPixel[(i-1)*height+j]*Template[1]+
tmpPixel[(i-1)*height+j+1]*Template[2]+tmpPixel[i*height+j-1]*Template[3]+tmpPixel[i*height+j]*Template[4]
+tmpPixel[i*height+j+1]*Template[5]+tmpPixel[(i+1)*height+j-1]*Template[6]+tmpPixel[(i+1)*height+j]*Template[7]
+tmpPixel[(i+1)*height+j+1]*Template[8];
}
}
}
//加权平均法平滑化函数
void MainWindow::YanMo2(int
*tmpPixel,
int width,
int height)
{
float Template[9]={1.0/16,2.0/16,1.0/16,2.0/16,4.0/16,2.0/16,1.0/16,2.0/16,1.0/16};
int i,j;
for(i=1;i<width-1;i++)
{
for(j=1;j<height-1;j++)
{
tmpPixel[i*height+j]=tmpPixel[(i-1)*height+j-1]*Template[0]+tmpPixel[(i-1)*height+j]*Template[1]+
tmpPixel[(i-1)*height+j+1]*Template[2]+tmpPixel[i*height+j-1]*Template[3]+tmpPixel[i*height+j]*Template[4]
+tmpPixel[i*height+j+1]*Template[5]+tmpPixel[(i+1)*height+j-1]*Template[6]+tmpPixel[(i+1)*height+j]*Template[7]
+tmpPixel[(i+1)*height+j+1]*Template[8];
}
}
}
下面是这段时间,我关于图像处理方面的一些入门算法的实现代码,使用qt实现的,为自己后期实现图像处理(如:图像变形、分割等)做准备,代码分享如下:
点击(此处)折叠或打开
#include \"mainwindow.h\"
#include \"ui_mainwindow.h\"
#include <QFileDialog>
#include <QMovie>
#include <QRgb>
#include <math.h>
#include <QInputDialog>
#include <QDebug>
#include <QDialog>
#include <QDoubleSpinBox>
#include <QSpinBox>
#include <QLabel>
MainWindow::MainWindow(QWidget
*parent)
:
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QMenu *editMenu=ui->menuBar->addMenu(QObject::tr(\"图片(&P)\"));
QAction *action_Open=editMenu->addAction(QObject::tr(\"打开图片&O\"));
QMenu *editMenuMake=ui->menuBar->addMenu(QObject::tr(\"图像几何变换(&M)\"));
QAction *action_Make1=editMenuMake->addAction(QObject::tr(\"图像平移(&T)\"));
QAction *action_Make2=editMenuMake->addAction(QObject::tr(\"图像放缩(&S)\"));
QMenu *editMenuBetter=ui->menuBar->addMenu(QObject::tr(\"图像增强(&B)\"));
QAction *action_Better1=editMenuBetter->addAction(QObject::tr(\"图像锐化(&E)\"));
QAction *action_Better2=editMenuBetter->addAction(QObject::tr(\"直方图均衡化(&A)\"));
QAction *action_Better3=editMenuBetter->addAction(QObject::tr(\"消除噪声(&D)\"));
QMenu *editMenuTiqu=ui->menuBar->addMenu(QObject::tr(\"提取(&G)\"));
QAction *action_Gray=editMenuTiqu->addAction(QObject::tr(\"图像灰度化\"));
QAction *action_Get1=editMenuTiqu->addAction(QObject::tr(\"Sobel算子提取\"));
action_Open->setCheckable(true);
action_Make1->setCheckable(true);
action_Make2->setCheckable(true);
action_Better1->setCheckable(true);
action_Better2->setCheckable(true);
action_Better3->setCheckable(true);
action_Gray->setCheckable(true);
action_Get1->setCheckable(true);
connect(action_Open,SIGNAL(triggered()),this,SLOT(OpenPicture()));
connect(action_Make1,SIGNAL(triggered()),this,SLOT(SetChangeValue()));
connect(action_Make2,SIGNAL(triggered()),this,SLOT(SetSouValue()));
connect(action_Better1,SIGNAL(triggered()),this,SLOT(SetBetterValue()));
connect(action_Better2,SIGNAL(triggered()),this,SLOT(MakePicAverage()));
connect(action_Gray,SIGNAL(triggered()),this,SLOT(RgbToGray()));
connect(action_Get1,SIGNAL(triggered()),this,SLOT(SobelGet()));
connect(action_Better3,SIGNAL(triggered()),this,SLOT(SelectYanKind()));
}
MainWindow::~MainWindow()
{
delete ui;
}
//获取要处理的图像并显示出来
void MainWindow::OpenPicture()
{
fileName=QFileDialog::getOpenFileName( this,tr(\"打开文件\"),\"/usr/local/Trolltech\",
tr(\"任何文件(*.*)\"\";;文本文件(*.txt)\"\";;XML文件(*.xml)\"\";;Images
(*.png *.xpm *.jpg)\"));
QMovie *move=new QMovie(fileName);
ui->label->move(50,100);
ui->label->setMovie(move);
move->start();
}
//确定图像左右、上下的平移量,并触发平移函数
void MainWindow::SetChangeValue()
{
dialog=new QDialog(this);
QLabel *WidthLabel=new QLabel(dialog);
WidthLabel->move(30,50);
WidthLabel->setText(tr(\"设置宽度的平移量\"));
setWidthChange=new QSpinBox(dialog);
setWidthChange->setMaximum(20);
setWidthChange->setMinimum(-20);
setWidthChange->move(180,50);
QLabel *HeightLabel=new QLabel(dialog);
HeightLabel->move(30,80);
HeightLabel->setText(tr(\"设置高度的平移量\"));
setHeightChange=new QSpinBox(dialog);
setHeightChange->setMaximum(20);
setHeightChange->setMinimum(-20);
setHeightChange->move(180,80);
QPushButton *button=new QPushButton(dialog);
button->move(180,120);
button->setText(tr(\"确定\"));
dialog->show();
connect(button,SIGNAL(clicked()),this,SLOT(ShowChangePic()));
}
//平移函数
void MainWindow::ShowChangePic()
{
image=new QImage(fileName);
QImage ChangeImage;
ChangeImage=QImage(image->width(),image->height(),QImage::Format_ARGB32);
QRgb rgb;
int width,height;
int i,j;
int widthOffset,heightOffset;
width=image->width();
height=image->height();
widthOffset=setWidthChange->value();
heightOffset=setHeightChange->value();
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
rgb=image->pixel(i,j);
if(ChangeImage.valid(i+widthOffset,j+heightOffset))
{
ChangeImage.setPixel(i+widthOffset,j+heightOffset,rgb);
}
}
}
ui->label_2->resize(ChangeImage.width(),ChangeImage.height());
ui->label_2->setPixmap(QPixmap::fromImage(ChangeImage));
delete image;
delete dialog;
}
//设置图像伸缩的比例并触发伸缩函数
void MainWindow::SetSouValue()
{
dialog=new QDialog(this);
QLabel *WidthLabel=new QLabel(dialog);
WidthLabel->move(30,50);
WidthLabel->setText(tr(\"设置宽度的缩放比例\"));
setWidthBi=new QDoubleSpinBox(dialog);
setWidthBi->setMaximum(20);
setWidthBi->setMinimum(0.1);
setWidthBi->move(180,50);
QLabel *HeightLabel=new QLabel(dialog);
HeightLabel->move(30,80);
HeightLabel->setText(tr(\"设置高度的缩放比例\"));
setHeightBi=new QDoubleSpinBox(dialog);
setHeightBi->setMaximum(20);
setHeightBi->setMinimum(0.1);
setHeightBi->move(180,80);
QPushButton *button=new QPushButton(dialog);
button->move(180,120);
button->setText(tr(\"确定\"));
dialog->show();
connect(button,SIGNAL(clicked()),this,SLOT(ShowSouPic()));
}
//伸缩函数
void MainWindow::ShowSouPic()
{
int width,height;
image=new QImage(fileName);
width=image->width();
height=image->height();
double x,y,r1,r2,g1,g2,b1,b2;
int i,j;
double width_bi,height_bi;
QRgb rgb00,rgb01,rgb10,rgb11;
int r,g,b;
QImage SouImage;
width_bi=setWidthBi->value();
height_bi=setHeightBi->value();
SouImage=QImage(width*width_bi,height*height_bi,QImage::Format_ARGB32);
for(i=0;i<width*width_bi;i++)
{
for(j=0;j<height*height_bi;j++)
{
x=i*(1/width_bi);
y=j*(1/height_bi);
//边界采用单线性插值
if(ceil(x)==0&&ceil(y)!=0)
{
rgb00=image->pixel(0,ceil(y)-1);
rgb01=image->pixel(0,ceil(y));
r=(ceil(y)-y)*qRed(rgb00)+(y-(ceil(y)-1))*qRed(rgb01);
g=(ceil(y)-y)*qGreen(rgb00)+(y-(ceil(y)-1))*qGreen(rgb01);
b=(ceil(y)-y)*qBlue(rgb00)+(y-(ceil(y)-1))*qBlue(rgb01);
SouImage.setPixel(i,j,qRgb(r,g,b));
}
if(ceil(y)==0&&ceil(y)!=0)
{
rgb00=image->pixel(ceil(x)-1,0);
rgb10=image->pixel(ceil(x),0);
r=(ceil(x)-x)*qRed(rgb00)+(x-(ceil(x)-1))*qRed(rgb10);
g=(ceil(x)-x)*qGreen(rgb00)+(x-(ceil(x)-1))*qGreen(rgb10);
b=(ceil(x)-x)*qBlue(rgb00)+(x-(ceil(x)-1))*qBlue(rgb10);
SouImage.setPixel(i,j,qRgb(r,g,b));
}
//(0,0)点特殊处理
if(ceil(y)==0&&ceil(y)==0)
{
rgb00=image->pixel(0,0);
SouImage.setPixel(i,j,rgb00);
}
//非边界采用双线性插值
if(ceil(x)!=0&&ceil(y)!=0)
{
rgb00=image->pixel(ceil(x)-1,ceil(y)-1);
rgb01=image->pixel(ceil(x)-1,ceil(y));
rgb10=image->pixel(ceil(x),ceil(y)-1);
rgb11=image->pixel(ceil(x),ceil(y));
r1=(ceil(x)-x)*qRed(rgb00)+(x-(ceil(x)-1))*qRed(rgb10);
r2=(ceil(x)-x)*qRed(rgb01)+(x-(ceil(x)-1))*qRed(rgb11);
r=(int)((ceil(y)-y)*r1+(y-(ceil(y)-1))*r2);
g1=(ceil(x)-x)*qGreen(rgb00)+(x-(ceil(x)-1))*qGreen(rgb10);
g2=(ceil(x)-x)*qGreen(rgb01)+(x-(ceil(x)-1))*qGreen(rgb11);
g=(int)((ceil(y)-y)*g1+(y-(ceil(y)-1))*g2);
b1=(ceil(x)-x)*qBlue(rgb00)+(x-(ceil(x)-1))*qBlue(rgb10);
b2=(ceil(x)-x)*qBlue(rgb01)+(x-(ceil(x)-1))*qBlue(rgb11);
b=(int)((ceil(y)-y)*b1+(y-(ceil(y)-1))*b2);
SouImage.setPixel(i,j,qRgb(r,g,b));
}
}
}
ui->label_2->resize(SouImage.width(),SouImage.height());
ui->label_2->setPixmap(QPixmap::fromImage(SouImage));
delete image;
delete dialog;
}
//设置图像锐化的阈值并触发图像锐化函数
void MainWindow::SetBetterValue()
{
dialog=new QDialog(this);
QLabel *WidthLabel=new QLabel(dialog);
WidthLabel->move(30,50);
WidthLabel->setText(tr(\"设置锐化的阈值\"));
setBetterValue=new QSpinBox(dialog);
setBetterValue->setMaximum(100);
setBetterValue->setMinimum(10);
setBetterValue->move(180,50);
QPushButton *button=new QPushButton(dialog);
button->move(180,70);
button->setText(tr(\"确定\"));
dialog->show();
connect(button,SIGNAL(clicked()),this,SLOT(MakePicBetter()));
}
//图像锐化
void MainWindow::MakePicBetter()
{
image=new QImage(fileName);
QImage ImageBetter;
ImageBetter=QImage(image->width(),image->height(),QImage::Format_ARGB32);
int i,j;
int r,g,b,tmpR,tmpG,tmpB;
QRgb rgb00,rgb01,rgb10;
int width=image->width(),height=image->height();
int betterValue=setBetterValue->value();
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
if(image->valid(i,j)&&image->valid(i+1,j)&&image->valid(i,j+1))
{
rgb00=image->pixel(i,j);
rgb01=image->pixel(i,j+1);
rgb10=image->pixel(i+1,j);
r=qRed(rgb00);
g=qGreen(rgb00);
b=qBlue(rgb00);
tmpR=abs(qRed(rgb00)-qRed(rgb01))+abs(qRed(rgb00)-qRed(rgb10));
tmpG=abs(qGreen(rgb00)-qGreen(rgb01))+abs(qGreen(rgb00)-qGreen(rgb10));
tmpB=abs(qBlue(rgb00)-qBlue(rgb01))+abs(qBlue(rgb00)-qBlue(rgb10));
if((tmpR+120)<255)
{
if(tmpR>betterValue)
{
r=tmpR+120;
}
}
else
{
r=255;
}
if((tmpG+120)<255)
{
if(tmpG>betterValue)
{
g=tmpG+120;
}
}
else
{
g=255;
}
if((tmpB+120)<255)
{
if(tmpB>betterValue)
{
b=tmpB+120;
}
}
else
{
b=255;
}
ImageBetter.setPixel(i,j,qRgb(r,g,b));
}
}
}
ui->label_2->resize(ImageBetter.width(),ImageBetter.height());
ui->label_2->setPixmap(QPixmap::fromImage(ImageBetter));
delete image;
delete dialog;
}
//图像的直方图均衡化
void MainWindow::MakePicAverage()
{
image=new QImage(fileName);
QImage ImageAverage;
ImageAverage=QImage(image->width(),image->height(),QImage::Format_ARGB32);
int i,j;
int width,height;
width=image->width();
height=image->height();
QRgb rgb;
int r[256],g[256],b[256];//原图各个灰度数量的统计
int rtmp,gtmp,btmp,rj,gj,bj;
float rPro[256],gPro[256],bPro[256];//原图各个灰度级的概率
float rTemp[256],gTemp[256],bTemp[256];//均衡化后各个灰度级的概率
int rJun[256],gJun[256],bJun[256];//均衡化后对应像素的值
memset(r,0,sizeof(r));
memset(g,0,sizeof(g));
memset(b,0,sizeof(b));
//获取原图各个灰度的数量
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
rgb=image->pixel(i,j);
r[qRed(rgb)]++;
g[qGreen(rgb)]++;
b[qBlue(rgb)]++;
}
}
//获取原图各个灰度级的概率
for(i=0;i<256;i++)
{
rPro[i]=(r[i]*1.0)/(width*height);
gPro[i]=(g[i]*1.0)/(width*height);
bPro[i]=(b[i]*1.0)/(width*height);
}
//均衡化后各个灰度级的概率,同时获取均衡化后对应像素的值
for(i=0;i<256;i++)
{
if(i==0)
{
rTemp[0]=rPro[0];
gTemp[0]=gPro[0];
bTemp[0]=bPro[0];
}
else
{
rTemp[i]=rTemp[i-1]+rPro[i];
gTemp[i]=gTemp[i-1]+gPro[i];
bTemp[i]=bTemp[i-1]+bPro[i];
}
rJun[i]=(int)(255*rTemp[i]+0.5);
gJun[i]=(int)(255*gTemp[i]+0.5);
bJun[i]=(int)(255*bTemp[i]+0.5);
}
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
rgb=image->pixel(i,j);
rtmp=qRed(rgb);
gtmp=qGreen(rgb);
btmp=qBlue(rgb);
rj=rJun[rtmp];
gj=gJun[gtmp];
bj=bJun[btmp];
ImageAverage.setPixel(i,j,qRgb(rj,gj,bj));
}
}
ui->label_2->resize(ImageAverage.width(),ImageAverage.height());
ui->label_2->setPixmap(QPixmap::fromImage(ImageAverage));
delete image;
}
//Sobel算子提取图像边界
void MainWindow::SobelGet()
{
image=new QImage(fileName);
QImage SobelIma;
SobelIma=QImage(image->width(),image->height(),QImage::Format_ARGB32);
Template(SobelIma);
ui->label_2->resize(SobelIma.width(),SobelIma.height());
ui->label_2->setPixmap(QPixmap::fromImage(SobelIma));
}
//与算子进行卷积的函数
void MainWindow::Template(QImage
&SobelImage)
{
int width=image->width(),height=image->height();
int pixelNum=width*height;
int i,j,k,l;
float rResult,gResult,bResult;
float sobel1[9]={1,2,1,0,0,0,-1,-2,-1},sobel2[9]={1,0,-1,2,0,-2,1,0,-1};
QRgb pixelOld[pixelNum],pixelTemp1[pixelNum],pixelTemp2[pixelNum];
int rtmp,gtmp,btmp;
memset(pixelTemp1,255,pixelNum);
memset(pixelTemp2,255,pixelNum);
QRgb tmpRgb;
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
tmpRgb=image->pixel(i,j);
pixelOld[j*width+i]=tmpRgb;
}
}
for(j=1;j<height-1;j++)
{
for(i=1;i<width-1;i++)
{
rResult=0;
gResult=0;
bResult=0;
for(k=0;k<3;k++)
{
for(l=0;l<3;l++)
{
rResult+=qRed(pixelOld[(j-1+k)*width+(i-1+l)])*sobel1[k*3+l];
gResult+=qGreen(pixelOld[(j-1+k)*width+(i-1+l)])*sobel1[k*3+l];
bResult+=qBlue(pixelOld[(j-1+k)*width+(i-1+l)])*sobel1[k*3+l];
}
}
rResult=(float)fabs(rResult);
gResult=(float)fabs(gResult);
bResult=(float)fabs(bResult);
if(rResult>255)
{
rtmp=255;
}
else
rtmp=(int)(rResult+0.5);
if(gResult>255)
gtmp=255;
else
gtmp=(int)(gResult+0.5);
if(bResult>255)
btmp=255;
else
btmp=(int)(bResult+0.5);
pixelTemp1[j*width+i]=qRgb(rtmp,gtmp,btmp);
}
}
for(j=1;j<height-1;j++)
{
for(i=1;i<width-1;i++)
{
rResult=0;
gResult=0;
bResult=0;
for(k=0;k<3;k++)
{
for(l=0;l<3;l++)
{
rResult+=qRed(pixelOld[(j-1+k)*width+(i-1+l)])*sobel2[k*3+l];
gResult+=qGreen(pixelOld[(j-1+k)*width+(i-1+l)])*sobel2[k*3+l];
bResult+=qBlue(pixelOld[(j-1+k)*width+(i-1+l)])*sobel2[k*3+l];
}
}
rResult=(float)fabs(rResult);
gResult=(float)fabs(gResult);
bResult=(float)fabs(bResult);
if(rResult>255)
rtmp=255;
else
rtmp=(int)(rResult+0.5);
if(gResult>255)
gtmp=255;
else
gtmp=(int)(gResult+0.5);
if(bResult>255)
btmp=255;
else
btmp=(int)(bResult+0.5);
pixelTemp2[j*width+i]=qRgb(rtmp,gtmp,btmp);
}
}
for(i=0;i<pixelNum;i++)
{
if(pixelTemp2[i]>pixelTemp1[i])
pixelTemp1[i]=pixelTemp2[i];
}
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
SobelImage.setPixel(i,j,pixelTemp1[j*width+i]);
}
}
delete[] pixelTemp1;
delete[] pixelTemp2;
delete image;
}
//设置图像平滑的方法
void MainWindow::SelectYanKind()
{
dialog=new QDialog(this);
QLabel *Label=new QLabel(dialog);
Label->move(45,20);
Label->setText(tr(\"设置图像平滑的方法\"));
QLabel *DescLabel=new QLabel(dialog);
DescLabel->move(60,45);
DescLabel->setText(tr(\" 1--邻域平均法\\n 2--加权平均法\\n
3--选择式掩膜平滑\\n\"));
setKind=new QSpinBox(dialog);
setKind->setMaximum(3);
setKind->setMinimum(1);
setKind->move(65,100);
QPushButton *button=new QPushButton(dialog);
button->move(65,130);
button->setText(tr(\"确定\"));
dialog->show();
connect(button,SIGNAL(clicked()),this,SLOT(DecreseVoice()));
}
//将图像的像素信息存在缓存中,并通过调用图像平滑函数更改缓存中的信息
void MainWindow::DecreseVoice()
{
image=new QImage(fileName);
int i,j,k,num;
int width=image->width(),height=image->height();
QImage MoreClear;
MoreClear=QImage(width,height,QImage::Format_ARGB32);
num=width*height;
QRgb tmpPixel[num];
int yanKind=setKind->value();
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
k=i*height+j;
tmpPixel[k]=image->pixel(i,j);
}
}
MoreClearPic(tmpPixel,yanKind,width,height);
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
k=i*height+j;
MoreClear.setPixel(i,j,tmpPixel[k]);
}
}
ui->label_2->resize(width,height);
ui->label_2->setPixmap(QPixmap::fromImage(MoreClear));
delete dialog;
}
//,图形平滑函数,它通过调用相应的平滑化函数实现图像的不同平滑化
void MainWindow::MoreClearPic(QRgb
*tmpPixel,int yanKind,int width,int
height)
{
int i,j,k;
int num=width*height;
int rtmpPixel[num],gtmpPixel[num],btmpPixel[num];
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
k=i*height+j;
rtmpPixel[k]=qRed(tmpPixel[k]);
gtmpPixel[k]=qGreen(tmpPixel[k]);
btmpPixel[k]=qBlue(tmpPixel[k]);
}
}
if(yanKind==1)
{
YanMo1(rtmpPixel,width,height);
YanMo1(gtmpPixel,width,height);
YanMo1(btmpPixel,width,height);
}
if(yanKind==2)
{
YanMo2(rtmpPixel,width,height);
YanMo2(gtmpPixel,width,height);
YanMo2(btmpPixel,width,height);
}
/*if(yanKind==3)
{
YanMo3(rtmpPixel,width,height);
YanMo3(gtmpPixel,width,height);
YanMo3(btmpPixel,width,height);
}*/
for(i=1;i<width-1;i++)
{
for(j=1;j<height-1;j++)
{
k=i*height+j;
tmpPixel[k]=qRgb(rtmpPixel[k],gtmpPixel[k],btmpPixel[k]);
}
}
}
//邻域平均法平滑化函数
void MainWindow::YanMo1(int
*tmpPixel,
int width,
int height)
{
float Template[9]={1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9,1.0/9};
int i,j;
for(i=1;i<width-1;i++)
{
for(j=1;j<height-1;j++)
{
tmpPixel[i*height+j]=tmpPixel[(i-1)*height+j-1]*Template[0]+tmpPixel[(i-1)*height+j]*Template[1]+
tmpPixel[(i-1)*height+j+1]*Template[2]+tmpPixel[i*height+j-1]*Template[3]+tmpPixel[i*height+j]*Template[4]
+tmpPixel[i*height+j+1]*Template[5]+tmpPixel[(i+1)*height+j-1]*Template[6]+tmpPixel[(i+1)*height+j]*Template[7]
+tmpPixel[(i+1)*height+j+1]*Template[8];
}
}
}
//加权平均法平滑化函数
void MainWindow::YanMo2(int
*tmpPixel,
int width,
int height)
{
float Template[9]={1.0/16,2.0/16,1.0/16,2.0/16,4.0/16,2.0/16,1.0/16,2.0/16,1.0/16};
int i,j;
for(i=1;i<width-1;i++)
{
for(j=1;j<height-1;j++)
{
tmpPixel[i*height+j]=tmpPixel[(i-1)*height+j-1]*Template[0]+tmpPixel[(i-1)*height+j]*Template[1]+
tmpPixel[(i-1)*height+j+1]*Template[2]+tmpPixel[i*height+j-1]*Template[3]+tmpPixel[i*height+j]*Template[4]
+tmpPixel[i*height+j+1]*Template[5]+tmpPixel[(i+1)*height+j-1]*Template[6]+tmpPixel[(i+1)*height+j]*Template[7]
+tmpPixel[(i+1)*height+j+1]*Template[8];
}
}
}
相关文章推荐
- Qt Mac 在软件 icns图标制作
- 从 Qt 的 delete 说开来
- Qt 的QString类的使用
- VS2010平台下VAssistX和Qt的整合配置及相关便捷操作
- QTableWidget 详细使用
- QT中QTableWidget的使用
- Qt ListView详细用法
- 如何让Qt应用程序只有一个实例
- QT5---QTableWidget简单应用之文件浏览器
- Qt中嵌入Directx11
- Qt中connect的一些使用细节
- 学习记录-Qt环境的编译
- Using Ogre paint Widget of QT
- QT事件(1)
- qt越来越好了
- Qt 多线程之MoveToThread()
- QT5的移植与错误总结
- QT调用CHM方法
- Qt5+VS2013 “LINK : fatal error LNK1117: 选项“VERSION:1.0.0”中的语法错误”
- Qt之显示图片