这一部分是图像相关的一些基础知识。学习了这部分知识之后,我发现里面提到一些关于相机、成像之类的内容,这些虽然跟计算机视觉相关,但感觉硬记下来也没办法转化成自己的知识。因此,类似的内容,就不强求自己去记住了。
1、分辨率
分辨率这个概念,相信在日常生活中也有遇到。图像分辨率和视频分辨率也有所不同。
图像分辨率指的是这张图像由几行几列构成。例如我输出一张图片的行数和列数:
string path = "xiaohuang.jpg";
Mat img = imread(path);
cout << "rows = " << img.rows << endl;
cout << "cols = " << img.cols << endl;
result:
rows = 1512
cols = 1080
然后打开这张图片的属性,可以发现代码中的行数和列数跟直接查看图片属性中的数值是对应的。
视频分辨率,例如1080p,指的是1920*1080,其中p指的是按行扫描。其实就是每一帧由1080行组成。1920和1080应该是遵从某个标准的,因此可以直接说1080,而不用强调列数。
正常来说分辨率越大,图像或视频的质量就越清晰。
2、图像灰度级
这里的级类似台阶的级,指取值的范围。例如像素值取值为0-255的话,就是256级。(这里不强调256是2^8,因为只要写了,就有误以为是8级的可能)。图像灰度值的概念并不是在灰度图才有。这里说的灰度可能会导致有些混淆,关键在于级,也就是取值范围。当然,这个概念也有可能是从灰度图引申到有色图的。在有色图中,rgb三个通道也有各自的灰度级,虽然这三个值一般也是一样的大小(这里说一般不是说有特殊情况,而是我不知道有没有特殊情况)。一般灰度越多,图像的细节就越多。写到这里突然想到一些其他的内容,灰度级也不是越多越好,有时候像素风格更让人喜欢。
3、图像坐标系
数学概念上的坐标系是向右向上的,图像坐标系是向右向下的,也就是说,一张图片,左上角才是原点。这一点就跟图像存储在计算机中的方式相吻合了。因为数组的第一行第一列,也就是图像的左上角,是存储在连续数据的开头的。
4、像素空间关系
像素空间关系指的是以自身为中心的3*3矩阵中,其余像素跟自身的关系。在八邻接关系中,其余八个像素都是中心像素的邻接像素;四邻接关系中,只有上下左右才是邻接像素,其余四个是非邻接像素。
5、二值图像
二值图像是指灰度图像中只有两种灰度,0和1或者0和255。一般是由正常图像转化得到的,通常是用于将背景和前景分开,例如把桌子和桌子上的硬币分开。
6、灰度图
单通道,像素值范围为0-255。
7、彩色图像
彩色图像有四种,分别是RGB、HSV、YCbCr、CMKY。
RGB图像偏重色彩显示,是彩色图像存储在计算机中的方式,这个比较常见,就不详细描述了。
灰度图和RGB图像可以互相转换。公式:Gray = R*0.299 + G*0.587 + B*0.114。直接取1/3的权重也可以得到近似的结果,但不如公式计算效果好。上述公式中各个权重不同是因为人眼对三种颜色的敏感度不同,对绿色最敏感,对蓝色最不敏感。至于权重的具体值应该是基于某些数据的来的。下面代码看一下两种转换的效果对比。
string path = "xiaohuang.jpg";
Mat img = imread(path);
imshow("xiaohuang", img);
waitKey();
int width = img.cols;
int height = img.rows;
Mat ave(height, width, CV_8UC1, Scalar(0));
Mat gray(height, width, CV_8UC1, Scalar(0));
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
Vec3b pixel = img.at<Vec3b>(i, j);
uchar ave_val = (pixel[0] + pixel[1] + pixel[2]) / 3;
ave.at<uchar>(i, j) = ave_val;
}
}
imshow("ave", ave);
waitKey();
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
Vec3b pixel = img.at<Vec3b>(i, j);
uchar ave_val = pixel[0] * 0.299 + pixel[1] * 0.587 + pixel[2] * 0.114;
gray.at<uchar>(i, j) = ave_val;
}
}
imshow("gray", gray);
waitKey();



学习过程中看到一种关于RGB应用于色彩校正的用法。在太空舱传回来的图像中,由于传输距离、信号等问题,图片可能存在失真,就是颜色的值不对了。可以在要拍摄的画面中放置一个标注的比色卡,然后根据图像中的比色卡跟真实的相对比,就可以一定程度上还原出真实的颜色了。不过误差肯定是存在的,因为颜色失真虽然有规律,但是规律肯定不是单一的。
HSV图像则偏重色彩描述,它更接近人脑对颜色的描述。从人接受颜色的角度来理解,RGB是原始数据,HSV是直观描述。其中H是色调,S是饱和度,V是亮度。RGB和HSV存在转换关系,不过这个部分我目前的理解很少,所以就不乱说了。
其余两种YCbCr是视频的数据,CMYK则应用在印刷行业中。这两种可能要到后面才会学习到。
8、直方图
灰度直方图是 像素值-像素值占比 的关系图。竖轴使用的是像素值个数占总个数的比例,而不是直接用像素值个数,因为其实元素值的个数并没有太大的用途,而使用比例的话就摆脱了原图像大小的影响了,有利于在其他方面的使用。
图像直方图可以用于图像相似度的匹配。把直方图当作一个(像素值,频率)的点的集合,计算欧几里得距离,也就是 对频率差值的平方进行累加然后开根号 ,其实就是n维空间计算点的距离然后累加再开根号,而横坐标恰好都对应相等。
灰度直方图可以用于画质的判断。可以通过像素值分布情况看出亮度是否合适以及曝光是否合适。
这一次的内容基本上都是关于图像的一些理论知识,涉及到代码的部分就比较少了,感觉有点乏味。