Mat A, C; // 只创建信息头部分
A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // 这里为矩阵开辟内存
Mat B(A); // 使用拷贝构造函数,浅拷贝(只拷贝矩阵头,但指向的仍是同一个阵列)
C = A; // 赋值运算符
对于Mat类庞大的计算量来自于矩阵的大小。所以要慎用深拷贝。
遍历图像的方法:
推荐的效率最高的查找表赋值方法:
uchar* p;
for( i = 0; i < nRows; ++i)
{
p = I.ptr(i);
for ( j = 0; j < nCols; ++j)
{
p[j] = table[p[j]];
}
}
这里,我们获取了每一行开始处的指针,然后遍历至该行末尾。如果矩阵是以连续方式存储的,我们只需请求一次指针、然后一路遍历下去就行。
彩色图像 的情况有必要加以注意:因为三个通道的原因,我们需要遍历的元素数目也是3倍。
filter2D 函数,用于计卷积,当核的尺寸小于11*11时,是直接计算,大于时,用的是dft计算。
addWeighted 函数,用于实现两个矩阵求和,但是两个矩阵的尺寸必须一致,否则没有意义。
公式:
dst(x,y)=∑kernel(x′,y′)∗src(x+x′−anchor.x,y+y′−anchor.y)
-------- 0≤y′---------rows0≤x′
convertTo() 函数,对像素进行线性变化
公式:
m(x,y)=saturate_cast(α(∗this)(x,y)+β)
滤波器:
滤波器都是为了平滑(模糊)图像,简单初步消除细碎的噪声。
归一化块滤波器 (Normalized Box Filter)
blur()
最简单的滤波器, 输出像素值是核窗口内像素值的 均值
高斯滤波器 (Gaussian Filter)
GaussianBlur()
最有用的滤波器 (尽管不是最快的)。
将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值 中间像素的加权系数是最大的,周边像素的加权系数随着它们远离中间像素的距离增大而逐渐减小 GaussianBlur() 最有用的滤波器 (尽管不是最快的) 将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值 中间像素的加权系数是最大的,周边像素的加权系数随着它们远离中间像素的距离增大而逐渐减小。
中值滤波器 (Median Filter)
medianBlur()
中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替 。即取邻域像素的中值。所以一般要求邻域是奇数。
双边滤波 (Bilateral Filter)
bilateralFilter()
上述这些滤波器不仅仅削弱了噪声, 连带着把边缘也给磨掉了。 为避免这样的情形 (至少在一定程度上 ), 我们可以使用双边滤波。
类似于高斯滤波器,双边滤波器也给每一个邻域像素分配一个加权系数。 这些加权系数包含两个部分,
第一部分加权方式与高斯滤波一样,第二部分的权重则取决于该邻域像素与当前像素的灰度差值。
在一定程度上,不仅可以消除噪声,还可以保证一定的边缘存在。
双边滤波器的参数,d:滤波器尺寸,sigmaColor:颜色范围的尺寸,sigmaSpace:
功能越强大的滤波器,计算量越大,原理也越复杂。
形态学:
形态学操作就是基于形状的一系列图像处理操作。通过将 结构元素 作用于输入图像来产生输出图像。
膨胀和腐蚀要灵活理解,对前景的膨胀等效于对背景的腐蚀。
放大缩小图像:
OpenCV中更常用的放大和缩小函数是resize函数。图像金字塔也是视觉运用中广泛采用的一项技术
图像金字塔:高斯金字塔(Gaussian pyramid): 用来向下采样;拉普拉斯金字塔(Laplacian pyramid): 用来从金字塔低层图像重建上层未采样图像
pyrUp放大:通过与内核卷积,获取“新增像素”的近似值
pyrDown缩小:通过与高斯内核卷积,将偶数行和列除去。结果图像只有原图的四分之一,
放大缩小,会导致图像的失真。
阈值化:
threshold
最简单的图像分割。是基于前景与背景之间的灰度差异。属于像素级分割。
阈值化类型:
梯度算子
OpenCV提供了 Scharr 函数,仅在内核大小为3时,该函数可用,且精度高于sobel,运行速度与sobel一样快。
convertScaleAbs,将图数值转换成绝对值。
RNG类,随机值
在进行边缘检测之前,opencv给的例子中,都进行了高斯滤波。消除部分噪声。
更复杂,更有效的算子:
Canny算子
边缘检测的最优算法:
检测其他:
霍夫线,圆检测:检测线和圆
霍夫线检测:普通坐标转换到极坐标
HoughLines:标准霍夫线变换
原理在上面的部分已经说明了. 它能给我们提供一组参数对 (ρ,θ) 的集合来表示检测到的直线
在OpenCV 中通过函数 HoughLines 来实现
HoughLinesP:统计概率霍夫线变换
这是执行起来效率更高的霍夫线变换. 它输出检测到的直线的端点 (x0, y0, x1, y1)
在OpenCV 中它通过函数 HoughLinesP 来实现
霍夫圆: HoughCircles
重映射
简单理解:对源图像重新映射一下。把阵列重新摆一下。
把一个图像中一个位置的像素放置到另一个图片指定位置的过程.
dst(x,y)=src(mapx(x,y),mapy(x,y))
源图像与目标图像的像素坐标不是一一对应的.所以有必要获得一些插值为非整数像素坐标 。
重映射,可以来实旋转和拉伸。期间,肯定会存在一些像素的丢失。
remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT,
Scalar(0,0, 0) ); map_x:x方向的映射; map_y:y方向的映射;两个map与src的大小要一致。
仿射变换:
一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移);
可以使用仿射变换来实现:缩放(线性变换),平移(向量加),旋转(线性变换)
warpAffine
这个先了解有这么个东西把,后面用到的时候,再去研究具体的算法。
直方图均衡化:
equalizeHist
直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法.
针对像素分布过于集中的情况下,表现为:图像过亮或者过暗。均衡化,可以均匀像素的分布,表现为调图像的对比度。
直方图:
calcHist
计算一个数组的分布。
normalize
归一化,将数组的值限定在某个范围内。
compareHist
对比两个直方图。可以对比图像的RGB直方分量,也可以对比HSV直方分量。
模板匹配
轮廓矩
使用OpenCV函数 moments 计算图像所有的矩(最高到3阶)
使用OpenCV函数 contourArea 来计算轮廓面积
使用OpenCV函数 arcLength 来计算轮廓或曲线长度
多边形测试
pointPolygonTest
特征,应该是独一无二的,在场景中很容易识别出来的特性。
图像特征类型:边缘;角点(感兴趣关键点);斑点(Blobs)(感兴趣区域)。
【角点】
【角点是两个边缘的连接点,它代表了两个边缘变化的方向上的点。图像梯度有很高的变化。这种变化是可以用来帮助检测角点的。】
cornerHarris角点检测; Harris-Stephens方法检测角点。梯度协方差矩阵
参数设置得不对,会崩溃的。而且算得很慢,慢,慢。
具体的算法,后期用到了,再分析。
Shi-Tomasi角点检测子:
goodFeaturesToTrack
不太懂,但是运行速度比cornersHarris快很多
自定义创建角点检测子:
cornerEigenValsAndVecs 来计算像素对应的本征值和本征向量来确定其是否是角点。
cornerMinEigenVal 通过最小化本征值来进行角点检测。
用上述两个函数实现一个定制化的Harris detector,类似Shi-Tomasi检测子。
亚像素级的角点检测:
cornerSubPix 寻找更精确的角点位置 (不是整数类型的位置,而是更精确的浮点类型位置)
SIFT 和 SURF是带专利的接口
-----------------------end------------------------------------------------
以上是自己简单尝试了一下,未做深入研究,不喜勿喷,欢迎拍砖以求斧正。学图像,隐隐约约觉得,算法的参数调试应该很复杂,而且图像能做出来的东西,应该可以很大,可以做成系统。可以作为研究课题。
它已经超出了一般应用的范围。而且,调试的手法也跟普通程序有一定的差别,普通程序,就是看看参数就好了,但是图像的调试可能要看图像的输出。看实际的效果,由人眼来判断是否达到要求。同时图像的调试不必拘泥于细枝末节,要关注整体。