数字图像处理上机实验

发布时间:2013-01-08 21:31:15   来源:文档文库   
字号:

数字图像处理上机实验一

注意:切勿抄袭!程序的功能段要有注释!

直方图均衡化算法

要求:

1在所给OpenCV例程的基础上(也可完全不用例程,自行实现),用C\C++实现教材中的直方图均衡化算法(不要直接调用OpenCV中的直方图均衡化函数,但可以参考)并对图像lenagray.bmp进行直方图均衡化,显示均衡化以后的新图像,将新图像保存在程序的当前文件夹下,图像命名为lenahisteqed.jpg

2.写出你在实现过程中遇到的主要难点及解决方案

#include "stdafx.h"

#include "cv.h"

#include "highgui.h"

#include"stdlib.h"

void imagechange(IplImage* img ,int channel);

int w[256]={0}; // 在此定义几个数组以存放中间结果,并且初始化。

int w1[256]={0};

int b[256]={0};

double b1[256]={0}; //要存放统计出来的概率

int main(int argc,char* argv[])

{

IplImage* img = cvLoadImage("C:\\OpenCV2.1\\samples\\c\\lenagray.BMP",1); //载入图像

IplImage* img1 = cvCloneImage(img);

imagechange(img,0); //将函数写在外面好处是对三个通道进行变换直接调用即可

imagechange(img,1);

imagechange(img,2);

cvNamedWindow("img",1);

cvNamedWindow("img1",1); //声明窗口及显示图像

cvShowImage("img",img);

cvShowImage("img1",img1);

cvWaitKey(0);

cvReleaseImage(&img);

cvReleaseImage(&img1);

cvDestroyWindow("img"); //释放图像,销毁窗口

cvDestroyWindow("img1");

}

void imagechange(IplImage* img ,int channel) //函数实现

{

int sum=0;

double sum1 = 0;

for(int k = 0;k<256;k++) //这个循环主要实现对级别的定义因为图像有级,所以事先对它定义有利于后面的比较。还可以利用它对所得结果进行保存

{

w[k]=k;

}

for(int i=0;iheight;i++) //这个循环实现对图像像素点的统计并且把相应的次数放到b数组中

{

for(int j=0;jwidthStep;j++)

{

for(int m=0;m<256;m++)

{

if(w[m]==((uchar *)(img->imageData+i*img->widthStep))[j*img->nChannels+channel])

{

b[m]=b[m]+1;

}

}

}

}

for(int i=0;i<256;i++) // 这个循环统计总的像素点的个数

{

sum +=(int)b[i];

}

// printf("%d\n",sum);

for( int j=0;j<256;j++)

{

b1[0]=(float)b[0]/sum ; //该循环实现相应像素级别在整个图像中所占的比例,并且实现将b[i]数组累加。后面要用到

if(j>1)

{

b1[j]=((float)b[j])/sum;

b1[j]=b1[j]+b1[j-1];

}

w1[j]=((int)(255*b1[j]+ 0.5)); //计算均匀化后每个点的像素

//printf("%d\n",w1[j]);

}

for(int i=0;iheight;i++) //该循环实现均匀化后的像素点送到图像中

{

for(int j=0;jwidthStep;j++)

{

for(int m=0;m<256;m++)

{

if(w[m]==((uchar *)(img->imageData+i*img->widthStep))[j*img->nChannels+channel])

{

((uchar *)(img->imageData+i*img->widthStep))[j*img->nChannels+channel]=w1[m];

}

}

}

}

}

数字图像处理上机实验二

注意:切勿抄袭!程序的功能段要有注释!

灰度图像中值滤波

要求:

1在所给OpenCV例程的基础上(也可完全不用例程,自行实现),用C\C++实现教材中的中值滤波算法(不要直接调用OpenCV中的中值滤波算法,但可以参考)并对图像lenagray.bmp进行5*5中值滤波,显示经过滤波新图像,将新图像保存在程序的当前文件夹下,图像命名为lenamidfilted.jpg

2.写出你在实现过程中遇到的主要难点及解决方法

程序:

// mediafilter.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include

#include

#include

#include

#include

#define iFilterH 5 //在这里定义一些宏是为了方便以后修改程序。好处是不涉及数字的改动只改变宏就可以

#define iFilterW 5

#define iFilterMX 2 //分别是滤波算子的宽和高,还有就是中心点的位置

#define iFilterMY 2

void imagechange(IplImage*,IplImage*,int channel); //变换函数证明

int main(int argc, char *argv[])

{

IplImage* img = NULL;

IplImage* img1=NULL;

img = cvLoadImage("C:\\OpenCV2.1\\samples\\c\\lenagray.bmp",0); //加载图像

img1=cvCloneImage(img); //克隆图像,目的是要用原来的数据进行计算而不是已经变换过的数据

imagechange(img,img1,0); //分别对三个通道的数据分别进行处理,img 是输入的图像,img1是变换后的图像

imagechange(img,img1,1); //后面的数字是通道数

imagechange(img,img1,2);

//一下就是声明窗口和显示图像以及释放图像销毁窗口

cvNamedWindow("mainWin",1);

cvNamedWindow("mainWin1",1);

cvShowImage("mainWin1", img1 );

cvShowImage("mainWin", img );

cvWaitKey(0);

cvReleaseImage(&img1 );

cvReleaseImage(&img );

cvDestroyWindow("mainWin");

cvDestroyWindow("mainWin1");

return 0;

}

void imagechange(IplImage* img,IplImage* img1,int channel) //变换函数

{

int height,width,step,channels; // 一些本数据的声明

uchar *data,*data1;

height = img->height;

width = img->width;

step = img->widthStep;

channels = img->nChannels;

data = (uchar *)img->imageData;

data1 = (uchar *)img1->imageData;

int pine=channel;

int filter[5][5]={0}; //滤波算子

int filter1[25]={0};

int media=0;

int i,j;

for( i= iFilterMX; i <= height-2; i++) //说明这里i=iFilterMX和i <= height-2 是因为算子图像的两行两列的边框进行处理。所以减掉

{

// 列(除去边缘几列)

for(j = iFilterMY;j<=step -2; j++)

{

// 读取滤波器数组

for (int k = 0;k

{

for (int l=0;l

{

filter[k][l] = data[(i+k)*step+(j+l)*channels+pine]; //和图像进行卷积运算

}

}

for(int m=0;m<5;m++)

{ for(int n=0;n<5;n++)

{

filter1[5*m+n]=filter[m][n];

}

}

int flag = 1;

for(int p=1;p<=24 && flag == 1;p++) //这个是对卷积后的结果进行排序,用的是冒泡法

{ for(int q=1;q<=24-p;q++)

{ int temp=0;

if(filter1[q]>filter1[q+1])

{

temp = filter1[q+1];

filter1[q+1] = filter1[q];

filter1[q] = temp;

flag = 1;

}

}

}

data1[i*step+j*channels+pine]=filter1[12]; 将排序后最大的结果赋给图像

}

}

}

数字图像处理上机实验三

请注意:切勿抄袭!程序的功能段要有注释!

灰度图像卷积运算及Sobel梯度

要求:

1.在所给OpenCV例程的基础上(也可完全不用例程,自行实现),用C\C++实现教材中的二维卷积算法(不要直接调用OpenCV中的函数,但可以参考),并对图像lenagray.bmp3*3Sobel算子进行卷积,并求得梯度幅值矩阵,Sobel算子如下:

-1

-2

-1

0

0

0

1

2

1

-1

0

1

-2

0

2

-1

0

1

将总梯度矩阵归一化为0255,以图像方式显示,将结果保存在程序的当前文件夹下,命名为lenasobel.jpg

2.写出你在实现过程中遇到的主要难点及解决方法。

程序:

// mediafilter.cpp : 定义控制台应用程序的入口点。

//

//在运行时只要改变cvloadImage即可

#include "stdafx.h"

#include

#include

#include

#include

#include

#define iFilterH 3 //定义一些宏//算子的长和宽.中心位置

#define iFilterW 3

#define iFilterMX 1

#define iFilterMY 1

void imagechange(IplImage*,IplImage*,int channel);

int main(int argc, char *argv[])

{

IplImage* img = NULL;

IplImage* img1=NULL;

img = cvLoadImage("C:\\OpenCV2.1\\samples\\c\\lena.jpg",0);//载图像

img1=cvCloneImage(img); //克隆图像用原始数据进行计算

imagechange(img,img1,0);

cvNamedWindow("mainWin",1);

cvNamedWindow("mainWin1",1); // 声明窗口和显示图像。释放图像销毁窗口

cvShowImage("mainWin1", img1 );

cvShowImage("mainWin", img );

cvWaitKey(0);

cvReleaseImage(&img1 );

cvReleaseImage(&img );

cvDestroyWindow("mainWin");

cvDestroyWindow("mainWin1");

return 0;

}

void imagechange(IplImage* img,IplImage* img1,int channel)

{

int height,width,step,channels;

uchar *data,*data1;

height = img->height;

width = img->width;

step = img->widthStep;

channels = img->nChannels;

data = (uchar *)img->imageData;

data1 = (uchar *)img1->imageData;

int pine=channel;

int sobel1[3][3]={-1,-2,-1,0,0,0,1,2,1}; //两个方向的算子

int sobel2[3][3]={-1,0,1,-2,0,2,-1,0,1};

int i,j;

for( i= iFilterMX; i <= height-1; i++) //对图像进行卷积。边框除外

{

for(j = iFilterMY;j<=step -1; j++)

{

int sumdata1 = 0;

int sumdata2 = 0;

int sumdata = 0;

for (int k = 0;k <=2;k++)

{

for (int m=0;m<=2;m++)

{

sumdata1 += data[(i+k)*step+(j+m)*channels+pine]*sobel1[k][m];

sumdata2 += data[(i+k)*step+(j+m)*channels+pine]*sobel2[k][m]; //将卷积后的数据放到sumdataX中

}

}

sumdata = abs(sumdata1)+abs(sumdata2); //将两个方向的梯度合并到一起,

if(sumdata>255) sumdata = 255; //防止溢出

data1[i*step+j*channels+pine]= sumdata; //将算出来的梯度赋给图像

}

}

}

数字图像处理上机实验四

请注意:切勿抄袭!程序的功能段要有注释!

基本全局门限

要求:

1.在所给OpenCV例程的基础上(也可完全不用例程,自行实现),用C\C++实现教材中的基本全局门限算法(不要直接调用OpenCV中的函数,但可以参考),对图像lenagray.bmp进行二值化,显示并将二值图像保存为lenagraybw.jpg

2.写出你在实现过程中遇到的主要难点及解决方法。

程序:

// cvprimarystep.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include

#include

#include

#include

#include

void Imagechange(IplImage*,IplImage*,int channel,int T);

int main(int argc, char *argv[])

{ IplImage* img=NULL;

IplImage* img1=NULL;

img = cvLoadImage("C:\\OpenCV2.1\\samples\\c\\lenagray.bmp",1);

img1 = cvCloneImage(img);

Imagechange(img,img1,0,150);

Imagechange(img,img1,1,150);

Imagechange(img,img1,2,150);

cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);

cvNamedWindow("mainWin1", CV_WINDOW_AUTOSIZE); //一些基本的图像加载和窗口显示

cvShowImage("mainWin", img );

cvShowImage("mainWin1", img1 );

cvWaitKey();

cvReleaseImage(&img );

cvReleaseImage(&img1 );

cvDestroyWindow("mainWin");

cvDestroyWindow("mainWin1");

return 0;

}

void Imagechange(IplImage* img,IplImage* img1,int channel,int T) //变换函数T是一个宏用来用来首次对图像进行分割

{

int height,width,step,channels;

uchar *data,*data1;

int i,j;

height = img->height;

width = img->width;

step = img->widthStep;

channels = img->nChannels;

data = (uchar *)img->imageData;

data1 = (uchar *)img1->imageData;

int flag = 1; //falg是一个标志。这个标志用来表示是否图像分割的分界点T与T1已经非常接近若接近那么flag为

//while循环退出

int T1=0;

while(flag)

{

int flag1 = 0;

int flag2 = 0;

int sum1= 0;

int sum2 =0;

for(i=0;i

{ for(j=0;j

{

if(data[i*step+j*channels+channel]>T)

{

flag1 = flag1+1;

sum1 += data[i*step+j*channels+channel];

}

else

{ flag2 = flag2+1;

sum2 += data[i*step+j*channels+channel];

}

}

}

sum1=int(double(sum1)/flag1);

sum2=int(double(sum2)/flag2);

T1 = int(double(sum1+sum2)/2);

if(abs(T1-T)<5)

{

flag = 0;

printf("%i",T1);

}

else

{ T=T1;

T1= 0;

}

}

for(i=0;i//再找到像素分界点T以后对图像进行二值化处理

{ for(j=0;j

{

if(data[i*step+j*channels+channel]>T1)

{ data1[i*step+j*channels+channel] = 255;

//printf("%i",data1[i*step+j*channels+channel]);

}

else

{ data1[i*step+j*channels+channel] = 0;

//printf("%i\n", data1[i*step+j*channels+channel]);

}

printf("%i\n",data1[i*step+j*channels+channel]);

}

}

}

数字图像处理上机实验五

请注意:切勿抄袭!程序的功能段要有注释!

实现Hough变换直线检测

要求:

1.在所给OpenCV例程的基础上(也可完全不用例程,自行实现),用C\C++实现教材中的Hoguh变换直线检测算法(不要直接调用OpenCV中的函数,但可以参考),对图像gantrycrane.pngcanny算子进行边界检测,并用你实现的Hough变换进行直线检测,将检测得到直线的在窗口显示(阈值可以自己设定)。

注意:如果能够将结果以逗号“,”分割,分行存入result.txt,将适当加分。

result.txt格式如下:

,

,

……

2.写出你在实现过程中遇到的主要难点及解决方法。

程序:

// cvprimarystep.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

////////////////////////////////////////////////////////////////////////

//

// hello-world.cpp

//

// 该程序从文件中读入一幅图像,将之反色,然后显示出来.

//

////////////////////////////////////////////////////////////////////////

#include

#include

#include

#include

#include

#include

int hough[500][360]={0}; //程序是用参数方程做的,对每一个点都有一个角度a和P对应

//而且P有可能是负值。在这里我事先声明两个数组一个用来存正的,另一个用来存负的

//并且对他们初始化

int hough1[500][360]={0};

#define T 100

#define T1 150 //这里是三个宏定义第一个是为了区分那些点点才能算得上是直线上的点

#define T2 180 //后两个是每一个p和a所对应的点数,用他们是为了提高程序运行速度

void Imagechange(IplImage*);

int main(int argc, char *argv[])

{ IplImage* img=NULL; //一些基本的加载和窗口函数

IplImage* img1=NULL;

img = cvLoadImage("C:\\OpenCV2.1\\samples\\c\\gantrycrane.png",0);

img1 = cvCloneImage(img);

cvCanny(img,img1,50,150,3);

Imagechange(img1);

//Imagechange(img1)

cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);

cvNamedWindow("mainWin1", CV_WINDOW_AUTOSIZE);

cvShowImage("mainWin", img );

cvShowImage("mainWin1", img1 );

cvWaitKey();

cvReleaseImage(&img );

cvReleaseImage(&img1 );

cvDestroyWindow("mainWin");

cvDestroyWindow("mainWin1");

return 0;

}

void Imagechange(IplImage* img) //变换函数

{

int height,width,step,channels;

uchar *data;

height = img->height;

width = img->width;

step = img->widthStep;

channels = img->nChannels;

data = (uchar *)img->imageData;

//printf("%i %i %i\n",height,step,height*step);

double sinvalue[360];

double cosvalue[360]; //这两个数组用来存放各个角度的sin值和cos值

for(int i=0;i<360;i++) //对各个角度的sin值和cos值进行初始化

{

sinvalue[i] = sin(i*3.141592653/180);

cosvalue[i] = cos(i*3.141592653/180);

}

for( int x=0;x//这个循环是对各个角度值计算各个图像像素点得p值

for(int y=0;y//并且对hough[p][a]这个数组相应位进行加一操作,记录每一个p和a出现的次数

//正的存放到hough里面负的存放到hough1里面,对他们分开处理

{

for(int i=0;i<360;i++)

{

if(data[x*step+y]>T)

{ int p = 0;

p = int(x*sinvalue[i] + y*cosvalue[i]);

if(p>=0)

{ hough[p][i]+=1;

}

else

{

hough1[abs(p)][i]+=1;

}

}

}

}

for( int x=0;x//为了能清晰的显示出图像做了一点处理

for(int y=0;y

{

data[x*step+y] = 0;

}

for(int i=0;i<500;i++) //这个循环是寻找直线的过程,对那些点数已经达到一定数目的p和a将它找出来

//并让这些相应的像素点的灰度值为,其他点得像素值为

for(int j=0;j<360;j++)

{

if(hough[i][j]>T1)

{ printf("p=%d a=%d hough=%d\n",i,j,hough[i][j]);

for( int x=0;x

for(int y=0;y

{

int p = 0;

p = int(x*sinvalue[j] + y*cosvalue[j]);

if(p==i)

{

data[x*step+y] = 255;

}

}

}

if(hough1[i][j]>T2)

{ printf("p=%d a=%d hough=%d\n",-i,j,hough1[i][j]);

for( int x=0;x

for(int y=0;y

{

int p = 0;

p = int(x*sinvalue[j] + y*cosvalue[j]);

if(p == -i)

{

data[x*step+y] = 255;

}

}

}

}

FILE *fp; //一下是一些文件操作将找到的p和a输出到c盘下的result文本下

errno_t err;

char * fp1="C:\\result.txt";

err = fopen_s(&fp,fp1,"a+");

if(err!=0) printf("创建失败");

for(int i=0;i<500;i++)

for(int j=0;j<360;j++)

{

if(hough[i][j]>T1)

{

char str[15]={0};

sprintf_s(str,"%d , %d\n",i,j);

fwrite(str,sizeof(str),1,fp);

}

if(hough1[i][j]>T2)

{

char str[15]={0};

sprintf_s(str,"%d , %d\n",-i,j);

fwrite(str,sizeof(str),1,fp);

}

}

fclose(fp);

}

本文来源:https://www.2haoxitong.net/k/doc/60f6a15877232f60ddcca1ad.html

《数字图像处理上机实验.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式