做造价在哪个网站查价格,专业的做网站公司,asp网站程序下载,各类网站网站建设的目标是什么意思我们首先了解一下什么是像素#xff0c;计算机中是如何存储图像#xff0c;以及opencv是如何表示图像的。
像素#xff1a;
像素是指由图像的小方格即所谓的像素(pixel)组成的#xff0c;这些小方块都有一个明确的位置和被分配的色彩数值#xff0c;而这些一小方格的颜色…我们首先了解一下什么是像素计算机中是如何存储图像以及opencv是如何表示图像的。
像素
像素是指由图像的小方格即所谓的像素(pixel)组成的这些小方块都有一个明确的位置和被分配的色彩数值而这些一小方格的颜色和位置就决定该图像所呈现出来的样子。可以将像素视为整个图像中不可分割的单位或者是元素不可分割的意思是它不能够再切割成更小单位抑或是元素它是以一个单一颜色的小格存在。每一个点阵图像包含了一定量的像素这些像素决定图像在屏幕上所呈现的大小
计算机存储图像
图像文件存储的都是每一个像素对应的颜色值。 1、位图文件有两种存储像素数据的格式。16777216色真彩色的图像一个像素的颜色可以用24位数据表示。256色的图像可以用调色板对颜色的信息进行编码一个像素的值对应的是调色板的索引而不是直接对应一个像素的颜色调色板的索引映射为像素的颜色。
2、以一百万个像素256种颜色的BMP文件在电脑上的存储为例。这个文件包括一个十四字节的文件首部一个四十字节的信息首部一个1024字节的颜色表一兆字节的位图数据。文件首部的前两个字节由字符BM组成还包括了文件长度和位图数据在文件中的起始位置。
3、文件的信息首部包含了图像的高、宽、颜色数等非图形数据。
这个图像共有一百万个像素一个像素需要八位的颜色信息文件的这一部分的长度是一百万个字节字节排放的顺序是自左到右从图像的最下面那行开始这个文件的总大小是1001078字节。
opencv表示图像
opencv中很多数据结构为了达到內存使用的最优化通常都会用它最小上限的空间来分配变量有的数据结构也会因为图像文件格式的关系而给予适当的变量因此需要知道它们声明的空间大小来配置适当的变量。一 般标准的图片为RGB格式它们的大小为8bits格式范围为0~255,对一个int空间的类型来说实在是太小整整浪费了24bits的空间,假设有个640*480的BMP文件空间存储內存,那整整浪费了640*480*3*(32-8)bits的內存空间,总共浪费了2.6MB!也就是那 2.6MB内什么东西都没存储如果今天以8bits的格式来存储则只使用到0.6MB的內存而已(640*480*3*(8)54 bits)因此对于文件格式的对应是一件很重要的事.。
访问像素的三种方法
指针访问迭代器iterator动态地址计算
首先我们来看一段代码
#includeopencv2/opencv.hpp
#includeiostream
using namespace std;
using namespace cv;
//指针操作访问像素
void colorReduce(Mat img,int div64)
{int nl img.rows;int nc img.cols*img.channels();for(int i 0;i nl;i){uchar* data img.ptruchar(i);for(int j 0 ; j nc;j){data[j] data[j]/div*div div/2;}}}
//迭代器模式
void ColorReduce(Mat img,int div 64)
{Mat_Vec3b::iterator it img.beginVec3b();Mat_Vec3b::iterator itend img.endVec3b();for (; it ! itend; it){(*it)[0] (*it)[0] / div * div div / 2;(*it)[1] (*it)[1] / div * div div / 2;(*it)[2] (*it)[2] / div * div div / 2;}namedWindow(dst);imshow(dst, img);
}
//动态地址计算
void colorReduce2(Mat img,int div 64)
{int cols img.cols;int rows img.rows;for(int i 0;i rows;i){for(int j0; j cols;j){img.atVec3b(i,j)[0] img.atVec3b(i,j)[0] / div * div div /2;img.atVec3b(i,j)[1] img.atVec3b(i,j)[1] / div * div div /2;img.atVec3b(i,j)[2] img.atVec3b(i,j)[2] / div * div div /2;}}
}int main(int argc,char** argv)
{Mat image imread(argv[1]);imshow(input,image);colorReduce2(image,64);imshow(dst,image);waitKey(0);destroyAllWindows();return 0;
}
指针操作
//指针操作访问像素
void colorReduce(Mat img,int div64)
{int nl img.rows; // 行数int nc img.cols*img.channels();//列数通道数 每一行像素的个数for(int i 0;i nl;i){//Mat类提供了函数可以得到任意行的首地址是一个模板函数uchar* data img.ptruchar(i); //获取第行的首地址for(int j 0 ; j nc;j){data[j] data[j]/div*div div/2;}}}
迭代器操作
//迭代器模式
void ColorReduce(Mat img,int div 64)
{Mat_Vec3b::iterator it img.beginVec3b();Mat_Vec3b::iterator itend img.endVec3b();for (; it ! itend; it){(*it)[0] (*it)[0] / div * div div / 2;(*it)[1] (*it)[1] / div * div div / 2;(*it)[2] (*it)[2] / div * div div / 2;}namedWindow(dst);imshow(dst, img);
}如果不熟悉迭代器模式可以阅读与中迭代器相关的资料。
动态地址计算
//动态地址计算
void colorReduce2(Mat img,int div 64)
{int cols img.cols; //列数int rows img.rows; //行数for(int i 0;i rows;i){for(int j0; j cols;j){ //处理蓝色通道img.atVec3b(i,j)[0] img.atVec3b(i,j)[0] / div * div div /2;//处理绿色通道img.atVec3b(i,j)[1] img.atVec3b(i,j)[1] / div * div div /2;//处理红色通道img.atVec3b(i,j)[2] img.atVec3b(i,j)[2] / div * div div /2;}}
}
对于彩色图像每个像素由三个部分蓝色通道绿色通道红色通道。因此对于一个包含彩色图像的会返回一个位数组组成的向量。将此向量定义为Vec3b即由usigned char 组成的向量。其访问像素通用表达式为
image.atVec3b(row,col)[channel] value;
其中索引值表示通道。
这就是访问像素的三种方法我们看一下效果