opencv从零开始——6. 图像的读取和像素遍历

一、 基础知识

(1) 将一幅图像视为一个二维函数f(x,y),以左上角为原点,x代表横轴,y代表纵轴。

(2) 图像分类:

二值图像:每个像素只有黑,白两种颜色。像素只有0和1两种取值,一般用0表示黑色,1表示白色。


灰度图像:在二值图像中,进一步加入许多介于黑白之间的颜色深度,就是灰度。每种灰度对应一个级别,通常用L表示。

RGB图像:通常将红色分为256个级别,绿色和蓝色也是一样。因此总共可以表达256*256*256种颜色。因为0~255的二进制表示为:0000 0000 ~ 1111 1111,因此需要8位才能表示一个颜色级别,而实际颜色是3原色混合的,因此通常需要24位组合成一个颜色。

例如下表:

红色0xFF0000
蓝色0x00FF00
绿色0x0000FF
黄色0xFFFF00
紫色0xFF00FF
白色0xFFFFFF
黑色0x000000
  
  

索引图像:如果每个像素都是24位,即3个字节来表示,图像文件巨大。例如一个200*200像素的图像,用RGB分量表示每个像素,那么图像大小=200*200*3(Byte)=120KB。假设这张图片只有16种颜色,那么每个像素只保存颜色的索引,这样就只需要4位,即0.5个字节来表示每个像素颜色,整个图像大小变为200*200*0.5=20KB,存储空间减小,而不会影响图片质量。

这就是常说的调色板(Palette),windows位图中应用到了调色板技术。

      

(3) 图像的空间分辨率

分辨率是指图像中每单位长度所包含的像素的数目。

例如72ppi表示图像中每英寸包含72个像素。


(4) 灰阶或者色阶

就是前面提到的灰度图的灰度级数L。



二、 读取图片的3通道

代码如下:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <vector>
#include <stdio.h>

using namespace std;
using namespace cv;

/** @函数 main */
//  /mnt/hgfs/code_for_Linux/code_opencv/test1/pic
int main( int argc, char** argv )
{
    Mat src;
    src = imread("/mnt/hgfs/code_for_Linux/code_opencv/test1/pic/2.jpg");
    imshow("原图", src);
    std::vector<Mat> channels;
    Mat aChannels[3];
    //src为要分离的Mat对象
    split(src, aChannels);              //利用数组分离
    split(src, channels);               //利用vector对象分离

    imshow("B",channels[0]);
    imshow("G",channels[1]);
    imshow("R",channels[2]);


    waitKey(0);
    return 0;

}

效果如下图所示:【原图】--【Blue】--【Green】--【Red】



可以明显的看出,不同的通道,显示的东西是有区别的


三、 imread

(1)功能:
读取一幅图像

(2)函数的声明格式:
Mat imread( const string& filename,int flags=1 );

(3)参数说明:
filename : 被读取的图像的名字
flags  说明读取图像的数据类型
如果flags>0 , 那么是把图像加载成3通道的彩色图像(注意:默认被加载成了一副彩色图像)
如果flags=0,那么把图像加载成灰度图(单通道的图像)
如果flags<0,那么如果图像本身是彩色图,就加载成彩色图,如果图像本身是灰度图就加载成灰度图。
如果图像加载失败,那么imread会返回一个空矩阵(Mat::data == NULL)


四、 遍历一张图的所有像素

代码例子如下:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <vector>
#include <stdio.h>

using namespace std;
using namespace cv;

/** @函数 main */
//  /mnt/hgfs/code_for_Linux/code_opencv/test1/pic

void colorReduce(Mat& image, int div)
{
    for(int i=0;i<image.rows;i++)
    {
        for(int j=0;j<image.cols;j++)
        {
            image.at<Vec3b>(i,j)[0]=image.at<Vec3b>(i,j)[0]/div*div+div/2;
            image.at<Vec3b>(i,j)[1]=image.at<Vec3b>(i,j)[1]/div*div+div/2;
            image.at<Vec3b>(i,j)[2]=image.at<Vec3b>(i,j)[2]/div*div+div/2;
        }
    }
}


int main( int argc, char** argv )
{
    Mat src, dst;
    src = imread("/mnt/hgfs/code_for_Linux/code_opencv/test1/pic/2.jpg");
    imshow("原图", src);

    colorReduce(src, 64);
    imshow("处理后的图", src);
    waitKey(0);
    return 0;
}

效果如下:



很明显,通过计算,操作了像素值,使得整个图片的效果下降了很多。

在很多博客里面,这叫 : colorReduce




五、 参考文献

[1] http://blog.csdn.net/ebowtang/article/details/41811135

[2] http://blog.csdn.net/daoqinglin/article/details/23628125





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值