最近开始了解图像处理的一些东西,曝一些读《数字图像处理与机器视觉--Visual C++与Matlab实现》的提要吧,和一个室友找的根据背景来追踪目标的简单代码。
提要:
0. 概述,提要本书的内容
1. matlab编程基础,关于matlab图像处理的部分
2. visual c++ 处理图像的部分,解释了封装好的处理图像的类和一个示例软件。
3. 图像的点变换,图像直方图的生成方式、线性点变换/非线性点变换的方式、灰度直方图的均衡化方法 点变换处理之后,可以使灰度趋于平缓,减少阴影的影响。
4. 图像的几何变换, 图像平移、镜像变换、缩放变换、旋转变换。插值算法:补充锥点变换(投影变换)之后的像素值。图像配准。例子:汽车牌照的斜角度拍摄照片的矫正变换。(可以考虑为歪斜角度的地面机器人也做这个变换来矫正,矫正为正面照)
5. 空间域图像增强,根据需求特定的增强图像中的某些信息,同时削弱或去除某些不重要的信息。其主要目的是使得处理后的图像更加适用。;不能增加原始图像的信息,只能增强对某种信息的辨别能力,同时也会带来信息丢失等其他信息。具体方法有:空间域滤波、图像平滑、中值滤波、图像锐化:使得模糊的图像更加清晰。
6. 频率域图像增强 这一章实现的东西和空间域图像增强的目标一致,只是处理方式不同。傅里叶变换。。。balabala….FFT等快速傅里叶变换balabala….
7. 彩色图像处理 主要讲了彩色图像的表达原理,还有一些彩色模型及不同模型之间变换的方式。
8. (重点)形态学图像处理 形态学效果可以用morphsimulator来模拟,有助于理解形态学算法变换的操作的意义。 腐蚀(边界区域处理),膨胀(与腐蚀相对应的操作),开运算(可以使得图像的轮廓变得光滑,还能使得狭窄的连接断开和消除毛刺) 闭运算(与开运算相对应,使得轮廓变得光滑,但是通常能够弥合狭窄的间断,填充小得孔洞)
9. (重点)图像分割 根据图像的不连续性:边缘检测、边界跟踪、hough变换 根据图像的相似性:区域生长、区域分裂与合并、阈值分割。 霍夫变换:是一种检测间断点边界形状的方法。它通过将图像坐标空间变换到参数空间,来实现直线和曲线的拟合。Hough变换对任意形状的检测。 阈值分割:设定不同阈值、迭代分割再叠加 区域生长算法(相似性判据:灰度值、纹理、颜色等) 区域分割然后拼接,根据拼接的步骤确定形状。
10.特征提取
(1)基本统计特征 简单的区域描绘子:周长、面积、灰度均值、灰度中值、包含区域的最小矩形、欧拉数。 直方图统计特征:灰度统计直方图,处理方式:直接将结果交给分类器;计算直方图的均值、方差、平滑度、三阶矩、一致性、熵组成一个向量。
(2) 特征降维 忽略无关的特征,只关注解决问题的核心特征可以降低特征的维度,提高精度(高维度特征反而降低精度)。
(3) 主成分分析(PCA) 降维方法。快速PCA 有函数可以直接调用。例子:基于PCA的人脸特征抽取 ,将PCA的处理结果运用到支持向量机(SVM)中进行分类,识别。
(4) 局部二进制模式 LBP,滤波的另一个版本,过程复杂但是效果好点
11. 图像识别初步:
整个的过程是一个机器学习的过程:
关于分类器,这本书里面给出了三个方向:最小距离分类器、人工神经网络分类器、支持向量机分类器。下面进行展开介绍:
最小距离分类器:例如运用样本的平均向量作为代表该类的原型。
基于相关的模板匹配:(能不能根据不同角度、不同高度的地面机器人的图像建立一个类似的图像库,然后将我们拍摄到的图像在图中寻找匹配,这样就会带来精度的问题。)
12.人工神经网络
过程没看懂….=_=…..大致是根据初始图像采样,然后建立模型,用采样数据训练模型,然后输入测试图像进行识别。例子实现了数字字符识别系统:即不同的东倒西歪大小各异的数字可以进行识别处理得到数字化存储的数值。
13.支持向量机
所谓支持向量是指那些在间隔区边缘的训练样本点。 这里的“机(machine,机器)”实际上是一个算法。在机器学习领域,常把一些算法看做是一个机器。
支持向量机(SVM)与神经网络类似,都是学习型的机制,但与神经网络不同的是SVM使用的是数学方法和优化技术。
SVM的关键在于核函数。低维空间向量集通常难于划分,解决的方法是将它们映射到高维空间。但这个办法带来的困难就是计算复杂度的增加,而核函数正好巧妙地解决了这个问题。也就是说,只要选用适当的核函数,就可以得到高维空间的分类函数。在SVM理论中,采用不同的核函数将导致不同的SVM算法。
核函数的确定并不困难,满足Mercer定理的函数都可以作为核函数。常用的核函数有:线性核函数,多项式和函数,径向基核函数,Sigmoid核函数和复合核函数。
代码:
1 #include <cv.h>
2 #include <cxcore.h>
3 #include <opencv2/opencv.hpp>
4 #include <highgui.h>
5
6 using namespace cv;
7
8 int main(int argc, char** argv)
9 {
10 //声明IplImage指针
11 Mat inp_image;
12 VideoCapture cam(0);
13
14 IplImage input_image;
15 IplImage* pFrame = &input_image;
16 //IplImage* pFrame = NULL;
17 IplImage* pFrImg = NULL;
18 IplImage* pBkImg = NULL;
19
20 CvMat* pFrameMat = NULL;
21 CvMat* pFrMat = NULL;
22 CvMat* pBkMat = NULL;
23
24 CvCapture* pCapture = NULL;
25 //
26
27 int nFrmNum = 0;
28
29 //创建窗口
30 cvNamedWindow("video", 1);
31 cvNamedWindow("background", 1);
32 cvNamedWindow("foreground", 1);
33 //使窗口有序排列
34 cvMoveWindow("video", 30, 0);
35 cvMoveWindow("background", 360, 0);
36 cvMoveWindow("foreground", 690, 0);
37
38
39
40 if (argc > 2)
41 {
42 fprintf(stderr, "Usage: bkgrd [video_file_name]\n");
43 return -1;
44 }
45 /*
46 //打开摄像头
47 if (argc == 1)
48 if (!(pCapture = cvCaptureFromCAM(0)))
49 {
50 fprintf(stderr, "Can not open camera.\n");
51 return -2;
52 }
53 */
54 //打开视频文件
55 if (argc == 2)
56 if (!(pCapture = cvCaptureFromFile(argv[1])))
57 {
58 fprintf(stderr, "Can not open video file %s\n", argv[1]);
59 return -2;
60 }
61
62 //逐帧读取视频
63 while (true)
64 {
65 cam >> inp_image;
66 input_image = inp_image;
67
68 nFrmNum++;
69
70 //如果是第一帧,需要申请内存,并初始化
71 if (nFrmNum == 1)
72 {
73 pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1);
74 pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1);
75
76 pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
77 pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
78 pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
79
80 //转化成单通道图像再处理
81 cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);
82 cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
83
84 cvConvert(pFrImg, pFrameMat);
85 cvConvert(pFrImg, pFrMat);
86 cvConvert(pFrImg, pBkMat);
87 }
88 else
89 {
90 cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
91 cvConvert(pFrImg, pFrameMat);
92 //高斯滤波先,以平滑图像
93 //cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
94
95 //当前帧跟背景图相减
96 cvAbsDiff(pFrameMat, pBkMat, pFrMat);
97
98 //二值化前景图
99 cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);
100
101 //进行形态学滤波,去掉噪音
102 //cvErode(pFrImg, pFrImg, 0, 1);
103 //cvDilate(pFrImg, pFrImg, 0, 1);
104
105 //更新背景
106 cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);
107 //将背景转化为图像格式,用以显示
108 cvConvert(pBkMat, pBkImg);
109
110 //显示图像
111 cvShowImage("video", pFrame);
112 cvShowImage("background", pBkImg);
113 cvShowImage("foreground", pFrImg);
114
115 //如果有按键事件,则跳出循环
116 //此等待也为cvShowImage函数提供时间完成显示
117 //等待时间可以根据CPU速度调整
118 if (cvWaitKey(2) >= 0)
119 break;
120
121
122 }
123
124 }
125
126
127
128
129 //销毁窗口
130 cvDestroyWindow("video");
131 cvDestroyWindow("background");
132 cvDestroyWindow("foreground");
133
134 //释放图像和矩阵
135 cvReleaseImage(&pFrImg);
136 cvReleaseImage(&pBkImg);
137
138 cvReleaseMat(&pFrameMat);
139 cvReleaseMat(&pFrMat);
140 cvReleaseMat(&pBkMat);
141 cvReleaseCapture(&pCapture);
142
143 return 0;
144 }
View Code