相机成像的小孔模型:
图像亮度与物体的辐照强度和传感器的光谱灵敏的决定,辐照强度指照射到像平面的“辐射能”在单位面积上的功率,而辐照强度又由场景辐射强度(光照强度)决定,它们成正比例关系,比例系数有成像系统的参数决定。
一个理想的透镜具有如下两个特征:1:它的投影方式和小孔模型相同;2,:将一定数量的光线汇聚到一起。完美的透镜系统中,射向透镜中心的光线不发生偏转,射向透镜边缘的光线将会偏转并和射向透镜中心的光线汇聚。但这一理想透镜只会对特定距离的物体才会准确聚焦,物体前后移动生成的光斑小于传感器分辨率的范围被称为成像域深度,也称景深。透镜直径越大,成像域深度就越小,因此在调节视觉系统时越有可能造成的聚焦误差。
任何简单透镜都会产生缺陷和像差,但根据理想简单透镜的成像原理和光路的可逆性,将一块透镜放到另一块透镜的焦距附近,可以提高成像质量,因此将多个透镜沿光轴仔细排列成为组合透镜。
不管是组合透镜还是简单透镜,其投影方式不可能和理想小孔模型一样,对所有光线的准确聚焦也是无法实现的,总会产生像差。但是对于一个设计精良的透镜系统,这些缺陷会尽可能的做到最小。
任何颜色都有红、绿、蓝三原色组成,在opencv中使用cvtColor函数使用COLOR_RGB2GRAY参数把彩色图转为灰度图。灰度是指黑白图像中的颜色深度,每个像素一般使用一个字节存储,范围为0-255,共256个灰度等级。白色为255,黑色为0。
灰度图的预处理包含逐像素处理和卷积处理等。逐像素处理针对每一个像素独立处理,处理前后同样位置的像素具有相同的映射关系,亮度变化,直方图均衡化属于逐像素处理操作。卷积处理后图中一个像素值与原图中多个像素值相关,滤波,特征点提取等都属于卷积操作。
对每个像素点独立进行函数运算,返回的仍然是图像,通常用于把机器视觉关注的特征凸显出来。
2.1.1图像二值化
图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。
图像二值化公式:
Mat ThresholdLAB(Mat src, Vec3d low, Vec3d high)
{
Mat bgr, lab, dst;
src.convertTo(bgr, CV_32FC3, 1.0 / 255, 0);
cvtColor(bgr, lab, CV_BGR2Lab);
Mat mask;
inRange(lab, Scalar(low[0], low[1], low[2]), Scalar(high[0], high[1], high[2]), mask);
Mat gray_all;
GaussianBlur(mask, gray_all, Size(3, 3), 0);
threshold(gray_all, gray_all, 100, 255, THRESH_BINARY);
Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
//去除瞄准十字
erode(gray_all, gray_all, element);
dilate(gray_all, gray_all, element);
return gray_all;
}
2.1.2亮度变换
亮度变换有两个功能,一是提高对比度,二是消除或者减轻因环境光照强度、物体表面反射、相机增益等引起的亮度变化。为了补偿这些因素,对图像进行转换,以使所得像素值的均值为0,方差为1。
在实际的图像处理中,如果认为图像的绝对亮度不包含视觉任务需求的关键信息,则可以使用这种方式对图像进行处理。
for (int i = 0; i < img.rows; i++)
{
for (int j = 0; j < img.cols; j++)
{
int tmp = img.at<uchar>(i, j);
double yy = (tmp - mean2) / stddev2*stddev1 + mean1;
yy = yy > 255 ? 255 : yy < 0 ? 0 : yy;
img.at<uchar>(i, j) = yy;
}
}
2.1.3直方图均衡化
图像的直方图可以反映图像的一些全局特征,比如偏暗,偏亮,亮度集中等。
数字图像处理中的预处理步骤很多属于卷积操作,各种滤波,特征提取等都是利用了卷积操作完成。进行卷积操作时,定义一个卷积核,使用这个卷积核和图像进行卷积,对于图像上的一个点,让卷积核的原点和该点重合,然后卷积核上的点和图像上对应的点相乘,然后各点的积相加,就得到了该点的卷积值。对图像上的每个点都进行相同处理。
2.2.1基于卷积运算的图像滤波
图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。
Opencv中提供的滤波器有方框滤波boxFilter,高斯滤波GaussianBlur,中值滤波medianBlur以及双边滤波bilateralFilter,前两者为线性滤波,后两者为非线性滤波。双边滤波严格上不属于卷积操作,因为卷积核在图像上滑动时会根据特征调整卷积核(权重)。
方框滤波器的卷积核为
2.2.2基于卷积运算的特征提取
特征提取是图象处理中的一个初级运算,它检查每个像素来确定该像素是否代表一个特征,因此一般作为更大的算法的一部分。图像中的特征指边,角,交叉,区域等。有些特征可以使用卷积的方式提取。
Robert 算子:Robert算子是一种种利用局部差分算子寻找边缘的算子,对具有陡峭的低噪声的图像效过较好。Robert算子的卷积核为:
Mat task4 = imread('pic/task4-2.jpg');
Mat gray,sobel1,sobel2,sobel;
cvtColor(task4, gray, COLOR_RGB2GRAY);
Sobel(gray, sobel1, CV_8U, 1, 0, 3);
Sobel(gray, sobel2, CV_8U, 0, 1, 3);
addWeighted(sobel1, 0.5, sobel2, 0.5, 0, sobel);
imshow('task4', task4);
imshow('sobel', sobel);
waitKey();
Soble算子处理效果:
Mat task5 = imread('pic/task4-3.jpg');
cvtColor(task5, task5, COLOR_BGR2GRAY);
Mat gray_all, laplacian;
GaussianBlur(task5, gray_all, Size(3, 3), 0);
Laplacian(task5, laplacian, CV_8U, 3);
imshow('task5', task5);
imshow('laplacian', laplacian);
waitKey();
Laplacian算子处理效果:
除了上面提到的使用逐像素操作和卷积操作提取图像边缘特征的操作外,数字图像处理中有更加高级的特征提取方法。
边界特征法该方法通过对边界特征的描述来获取图像的形状参数,其中Hough变换检测平行直线方法和边界方向直方图方法是经典方法。
Hough 变换是利用图像全局特性而将边缘像素连接起来组成区域封闭边界的一种方法,其基本思想是点—线的对偶性;
边界方向直方图法首先微分图像求得图像边缘,然后,做出关于边缘大小和方向的直方图,通常的方法是构造图像灰度梯度方向矩阵。
Hough直线检测代码:
Mat srcImage = imread('pic/task9-2.jpg'),gray,show;
show = srcImage.clone();
cvtColor(srcImage, gray, COLOR_RGB2GRAY);
Canny(gray, gray, 100, 200, 3, false);
vector<Vec2f> lines;HoughLines(gray, lines, 1.0, CV_PI / 60, 100, 0, 0);
RNG rng(time(0));
for (size_t i = 0; i < lines.size(); i++)
{
int rand1 = rng.uniform(0, 150);
int rand2 = rng.uniform(0, 150);
int rand3 = rng.uniform(0, 150);
float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = arho, y0 = brho;
pt1.x = cvRound(x0 + 2000 (-b)); //把浮点数转化成整数
pt1.y = cvRound(y0 + 2000 (a));
pt2.x = cvRound(x0 - 2000 (-b));
pt2.y = cvRound(y0 - 2000 (a));
line(show, pt1, pt2, Scalar(rand1, rand2, rand3), 4, LINE_AA);
}
imshow('output', show);
waitKey();
Hough直线检测实验效果:
形状的表达和匹配采用更为简单的区域特征描述方法,例如采用形状定量测度比如面积、周长,一阶矩,二阶矩,不变矩等形状参数。形状最小包围矩形的面积,周长,长边方向等,对于椭圆等形状,可以利用圆度、偏心率、主轴方向等几何参数,进行基于形状特征的图像检索。形状参数的提取,必须以图像处理及图像分割为前提,几何参数的准确性必然受到图像分割效果的影响,对分割效果很差的图像,几何参数甚至无法提取。
3.2.1轮廓面积和周长
在Opencv中使用contourArea计算轮廓的面积,单位是像素个数;使用arcLength来计算轮廓和曲线的长度。
轮廓的面积和周长可以用来筛选目标,轮廓面积和周长的比例和目标的细长程度有关,也可作为筛选条件。
3.2.2图像的矩
矩函数在模式识别、目标分类、目标识别与方位估计、图像的编码与重构等都有广泛应用。从一幅图像计算出来的矩,不仅可以描述图像形状的全局特征,而且可以提供大量关于该图像不同的几何特征信息,如大小,位置、方向和形状等。图像矩这种描述能力广泛应用于各种图像处理、计算机视觉和机器人技术领域的目标识别与方位估计中。
一阶矩与形状有关系,可以用来计算重心,二阶矩表示目标相对原点扩展程度,不具有选择不变性,三阶矩不单独使用,和二阶矩组合可以得到Hu不变矩,具有旋转,平移,缩放不变性,用来做匹配。Opencv中函数moments用来计算矩,使用Humoments计算Hu不变矩。Opencv模板匹配函数matchShape使用Hu不变矩进行模板匹配并给出匹配参数。
string path = 'pic/task6-' + to_string(i+4) + '.png';
Mat task6 = imread(path, IMREAD_GRAYSCALE);
threshold(task6, task6,100,255, THRESH_BINARY);
Moments mu = moments(task6, true);
double humoments[7];
HuMoments(mu, humoments);
for (int j = 0; j < 7; j++)
{
humoments[j] = -1 copysign(1.0, humoments[j]) log10(abs(humoments[j]));
cout << 'Hu[' << j << ']:' << humoments[j] << endl;
}
cout << endl;
OpenCV中除了对整幅图像计算Hu矩外,还可以对轮廓计算Hu矩,因此可以对轮廓进行旋转平移缩放不变的轮廓匹配,OpenCV中实现函数是matchShape。其衡量两个轮廓匹配好坏的指标函数可以通过参数指定,共有三种,分别是:
3.3.1 Harris角点检测
Harris角点检测的基本思想:算法基本思想是使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么可以认为该窗口中存在角点。
Harris角点检测可以分为5个步骤:
Mat show = imread('pic/task9-1.jpg');
Mat srcImage, dst, norm_dst;
cvtColor(show, srcImage, COLOR_RGB2GRAY);cornerHarris(srcImage, dst, 2, 3, 0.04);
normalize(dst, norm_dst, 0, 255, NORM_MINMAX, CV_8UC1, Mat()); //CV_32FC1
for (int i = 0; i < srcImage.rows; i++)
for (int j = 0; j < srcImage.cols; j++)
if (norm_dst.at<uchar>(i, j) > 128)
circle(show, Point(j, i), 1, Scalar(0, 255, 0), 2);
imshow('show', show);
waitKey();
加粗样式
尺度空间极值检测:搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。
关键点定位:在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。
方向确定:基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。
关键点描述:在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。
SIFT算法在OpenCV中的contrib的SIFT_Impl中实现。
3.3.3 SURF 特征检测
SURF是speeded up roubst feature的简称,在不同尺度空间定位关键点,并给出每个点的特征向量。SURF特征检测的步骤:
1.尺度空间的极值检测:搜索所有尺度空间上的图像,通过Hessian来识别潜在的对尺度和选择不变的兴趣点。
2.特征点过滤并进行精确定位。
3.特征方向赋值:统计特征点圆形邻域内的Harr小波特征。即在60度扇形内,每次将60度扇形区域旋转0.2弧度进行统计,将值最大的那个扇形的方向作为该特征点的主方向。
4.特征点描述:沿着特征点主方向周围的邻域内,取4×4×4个矩形小区域,统计每个小区域的Haar特征,然后每个区域得到一个4维的特征向量。一个特征点共有64维的特征向量作为SURF特征的描述子。
SURF算法OpenCV中的contrib的SURF_Impl中实现。
3.3.4 FAST角点检测
Fast算法的思想是:角点所在像素和周围领域像素差别较大,因此,检测一个像素邻域有多少与处在不同区域,即像素值相差较大的像素个数。相差较大的像素个数越多,该点越有可能是角点。
FAST算法步骤:
Mat srcImage = imread('pic/task9-1.jpg', IMREAD_GRAYSCALE);
vector<KeyPoint>detectKeyPoint;
Mat keyPointImage;
Ptr<FastFeatureDetector> fast = FastFeatureDetector::create();
fast->detect(srcImage, detectKeyPoint);
drawKeypoints(srcImage, detectKeyPoint, keyPointImage, Scalar(0, 0, 255));
imshow('src image', srcImage);
imshow('keyPoint image', keyPointImage);
imwrite('pic/pic/task9-1.jpg', keyPointImage);
waitKey();
联系客服