您的位置:首页 > 编程语言 > Qt开发

图像处理之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];

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: