视力系统
视力要求眼睛对目标由选择性聚焦的能力,是通过睫状肌实现。
瞳孔控制进光量
人类感光元分成两类:视锥细胞、视杆细胞都是视网膜上的光感受器,
视杆细胞主要感受弱光、暗视觉以及没有颜色的视觉,黑白视觉。对明暗分辨敏感,光很微弱时调用视杆细胞。
视锥细胞主要感受强光、明视觉以及有颜色的视觉。有三种短波、中波、长波、分别感应蓝色、绿色和红色,视锥小标的总体响应是三类细胞的总和。在明亮情况下,相对暗的成像在视杆细胞上,亮出成像在视锥细胞。
眼睛具有马赫带先天特性,当观察两块亮度不同的区域时,边界处亮度对比加强,使轮廓表现得特别明显。
神经系统
眼睛产生的神经信号就是两类感受器细胞传送的响应,然后先用对数函数进行转换,再根据权重因子来调节某一个特定光感元的贡献。然后视觉信息传送到LGN中进行编码,LGN把信息传给视觉皮层。
处理系统
神经信号被传送到大脑的两个区域:联络皮层和枕叶皮层。联络皮层建立的是目标之间的连接,枕叶负责处理模式。但是很难精确判断具体发生了什么,因此现在只能用心理模型来推测大脑是如何工作的。
人类视觉系统可以轻易的判断出目标的边界,并且联想和填充,对损失的边界进行填充。
人类的视觉是可以被欺骗的,艾宾浩斯错觉和措尔纳错觉
第三章 图像基本运算
1.直方图
灰度直方图也称亮度直方图(Brightness histogram)。
图像的像素值大小用灰度来描述,通常而言灰度值范围为【0,255】,也称为灰度级。而灰度直方图(Gray histogram)是关于灰度级的分布函数,是图像灰度级分布的统计。简单地说,灰度直方图就是将图像中所有的像素点,按照灰度值的大小,统计其出现的频率。因此,灰度直方图是灰度级的函数,它表示了图像中具有某种灰度级(亮度)的像素个数,反映了图像中某种灰度级(亮度)出现的频率。
2.直方图均衡化
通过调整图像的灰阶分布,使得在0~255灰阶上的分布更加均衡,提高了图像的对比度,达到改善图像主观视觉效果的目的。对比度较低的图像适合使用直方图均衡化方法来增强图像细节。
merge(imageRGB, 3, image);
3.直方图(亮度)正规化
亮度进行扩展和位移,例如原来的亮度在50-100之间,线性映射到0-255。就像数据的正则化,标准划的操作。
normalize(src,dst,255,0,NORM_MINMAX,CV_8U);
4.点运算
它能让用户改变图像数据占据的灰度范围,当显示一幅图像时,点运算的作用尤其明显。比较暴力,直接对像素值进行线性或非线性变换。数值大了,图像自然就亮了
#include
#include
using namespace std;
using namespace cv;
void main()
{
Mat image,image1,image2,image3,image4, image5;
image = imread("C:\\Users\\10092\\Desktop\\1.jpg");
imshow("原图像", image);
Mat imageRGB[3];
split(image, imageRGB);
for (int i = 0; i < 3; i++)
{
equalizeHist(imageRGB[i], imageRGB[i]);
}
merge(imageRGB, 3, image1);
imshow("直方图均衡化图像增强效果", image1);
Mat kernel = (Mat_(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(image, image2, CV_8UC3, kernel);
merge(imageRGB, 3, image1);
imshow("拉普拉斯算子", image2);
//RGB三通道分离
split(image, imageRGB);
//求原始图像的RGB分量的均值
double R, G, B;
B = mean(imageRGB[0])[0];
G = mean(imageRGB[1])[0];
R = mean(imageRGB[2])[0];
cout << B << " " << G << " " << R << endl;
//需要调整的RGB分量的增益
double KR, KG, KB;
KB = (R + G + B) / (3 * B);
KG = (R + G + B) / (3 * G);
KR = (R + G + B) / (3 * R);
//调整RGB三个通道各自的值
imageRGB[0] = imageRGB[0] * KB;
imageRGB[1] = imageRGB[1] * KG;
imageRGB[2] = imageRGB[2] * KR;
//RGB三通道图像合并
merge(imageRGB, 3,image3);
imshow("白平衡调整后", image3);
Mat imageLog(image.size(), CV_32FC3);
for (int i = 0; i < image.rows; i++)
{
for (int j = 0; j < image.cols; j++)
{
imageLog.at(i, j)[0] = log(1 + image.at(i, j)[0]);
imageLog.at(i, j)[1] = log(1 + image.at(i, j)[1]);
imageLog.at(i, j)[2] = log(1 + image.at(i, j)[2]);
}
}
//归一化到0~255
normalize(imageLog, imageLog, 0, 255, CV_MINMAX);
//转换成8bit图像显示
convertScaleAbs(imageLog, imageLog);
imshow("Log变换", imageLog);
Mat imageGamma(image.size(), CV_32FC3);
for (int i = 0; i < image.rows; i++)
{
for (int j = 0; j < image.cols; j++)
{
imageGamma.at(i, j)[0] = (image.at(i, j)[0]) * (image.at(i, j)[0]) * (image.at(i, j)[0]);
imageGamma.at(i, j)[1] = (image.at(i, j)[1]) * (image.at(i, j)[1]) * (image.at(i, j)[1]);
imageGamma.at(i, j)[2] = (image.at(i, j)[2]) * (image.at(i, j)[2]) * (image.at(i, j)[2]);
}
}
//归一化到0~255
normalize(imageGamma, imageGamma, 0, 255, CV_MINMAX);
//转换成8bit图像显示
convertScaleAbs(imageGamma, imageGamma);
imshow("伽马变换图像增强效果", imageGamma);
double mean, stddev;
Mat temp_m, temp_sd;
meanStdDev(image, temp_m, temp_sd);
mean = temp_m.at(0, 0) / 255.0;
stddev = temp_sd.at(0, 0) / 255.0;
Mat temp_image(image.rows, image.cols, CV_64F);
for (int i = 0; i < image.rows; i++)
for (int j = 0; j < image.cols; j++) {
double pixelVal = image.at(i, j) / 255.0;
double temp = (pixelVal - mean) / stddev;
temp_image.at(i, j) = temp;
}
double max, min;
minMaxLoc(temp_image, &min, &max);
for (int i = 0; i < image.rows; i++)
for (int j = 0; j < image.cols; j++)
{
double pixelVal = temp_image.at(i, j);
image.at(i, j) = (uchar)round(255.0 * (pixelVal - min) / (max - min));
}
imshow("whitening", image);
Mat dst;
normalize(image , dst, 255, 100, NORM_MINMAX, CV_8U);
imshow("直方图正规化", dst);![QQ截图20210108142259.jpg](https://upload-images.jianshu.io/upload_images/23550723-9be5b18062dcf968.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
waitKey();
}
5.群运算
这本书里提出一个概念叫群运算,就是卷积运算、算子、滤波
同时解释了问什么卷积的大小通常是奇数
为了方标找到模板中心的位置。
平均算子有个特点:规模越大保留的边界就越大,规模越小保留的细节越多
平均算子
均值滤波是一种线性滤波,这种算法效率高,思路简单。这是因为在进行均值滤时,只需要把目标区域的像素值求平均再赋值给中心点就可以了。均值滤波的缺陷在于不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,像素都变的平均化了,从而使得图像变得模糊,特别是椒盐噪声
高斯平均算子
就是高斯滤波,运用高斯函数来计算,模板中的权值。一个二维的正态分布
中值滤波
中值滤波的基本思想是用矩阵中数据的中位数来代替矩阵中中间位置的值,所以中值滤波是一种非线性滤波技术。一般使用中值滤波器来去除椒盐噪声
椒盐噪声、脉冲噪声
"椒颗粒"是黑色,"盐颗粒"是白色在仿真实验中,我们可以通过随机生成一些图像内的像素位置,并这些像素点赋值为0或255来模拟
高斯噪声
高斯噪声中的噪声的概率密度函数是服从正态分布的,这些噪声大多情况都是因为传感器引起的。高斯噪声是随机的产生满足高斯分布的随机数,并且噪点不是简单的黑和白,有着多样性。
综合实验
//椒盐噪声发生器
void add_salt_pepper_noise(Mat& image)
{
RNG rng(12345);//随机数生成器
int h = image.rows;
int w = image.cols;
int nums = 10000;
for (int i = 0; i < nums; i++) {
int x = rng.uniform(0, w);//产生一个均匀分布的随机数,范围是0-w
int y = rng.uniform(0, h);
if (i % 2 == 1) {
image.at(y, x) = Vec3b(255, 255, 255);
}
else {
image.at(y, x) = Vec3b(0, 0, 0);
}
}
namedWindow("salt pepper", WINDOW_AUTOSIZE);
imshow("salt pepper", image);//展示
imwrite("C:\\Users\\Administrator\\Desktop\\4.jpg", image);//保存在本地
}
//高斯噪声发生器
void gaussian_noise(Mat& image) {
Mat noise = Mat::zeros(image.size(), image.type());//建立一张大小通道一样的黑色图片。
randn(noise, (15, 15, 15), (50,50, 50));建立复合正态分布的随机数,噪声均值是15,标准差是30;
Mat dst;
add(image, noise, dst);
imshow("gaussian noise", dst); //展示
imwrite("C:\\Users\\Administrator\\Desktop\\5.jpg", dst); //保存在本地
}
int main()
{
Mat srcImage=imread("1.jpg");//读入原图
namedWindow("高斯滤波[原图]");
namedWindow("高斯滤波[效果图]");
imshow("高斯滤波[原图]",srcImage);
//进行高斯滤波操作
Mat dstImage1;
GaussianBlur(srcImage,dstImage1,Size(5,5),0,0);
//显示效果图
imshow("高斯滤波[效果图]",dstImage);
namedWindow("均值滤波[原图]");
namedWindow("均值滤波[效果图]");
//进行滤波操作
Mat dstImage2;
blur(srcImage, dstImage2,Size(7,7));
//显示
imshow("均值滤波[原图]", srcImage);
imshow("均值滤波[效果图]", dstImage2);
namedWindow("中值滤波[原图]");
namedWindow("中值滤波[效果图]");
//进行滤波操作
Mat dstImage3;
medianBlur (srcImage, dstImage3,7);
//显示
imshow("中值滤波[原图]", srcImage);
imshow("中值滤波[效果图]", dstImage2);
waitKey(0);
return 0;
}
截断中值滤波
噪声的分布在理论上是不连续的,所以是非高斯分布的,假设图像的平均值、中值和模式(没搞懂可能是翻译问题,模式我理解就是该点的数值)次序是一致的。那么把分布截断掉,就是去除掉一部分点,那么截断分布的中值应该是接近与原始分布没噪声的图像值的
3.23中就是把大于平均值的点都删除了,然后用中值滤波来代替
双边滤波
在高斯滤波的基础上加入了像素值权重项,也就是说既要考虑距离因素,也要考虑像素值差异的影响,像素值越相近,权重越大。将像素值权重表示为 G r ,空间距离权重表示为 G s
当图像在变化程度平缓的区域时,邻域中的像素值(RGB值)差距相差不大。此时的双边就是普通的高斯滤波,达到对图像平滑的效果。
当图像在变化程度剧烈的区域,比如在边缘区域时,邻域中的像素值(RGB值)差距相差很大。此时gr朝0值趋近,颜色差值越大,gr越逼近0,最终整个式子的值逼近于0。
bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )
d表示在过滤过程中每个像素邻域的直径范围。
sigmaColor: 颜色空间过滤器的sigma值,这个参数的值越大,表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。
一个是gr方差一个是gs的方差
int main(void)
{
Mat src = cv::imread("C:\\Users\\10092\\Desktop\\4.jpg");
Mat dst;
// 滤波 N越大越平越模糊(2*N+1) sigmas空间越大越模糊sigmar相似因子
bilateralFilter(src, dst, 50, 70, 50);
imshow("原图", src);
imshow("双边滤波", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
各向异性扩散
之前的用于平滑的滤波,都是降低图像的辨识度,让图像特征的边界变得模糊,使得图像的细节减少。就提出了新的
各向异性扩散,也叫做P–M扩散,在图像处理和计算机视觉中广泛用于保持图像细节特征的同时减少噪声。
太难了,还没看懂,慢慢看。