转自:http://blog.csdn.net/skeeee/article/details/13297457
OpenCV图像像素操作及效率分析
在计算机视觉应用中,对于图像内容的读取分析是第一步,所以学习高效的处理图像是很有用的。一个图像有可能包含数以万计的像素,从根本上说图像就是一系列像素值,所以OpenCV使用数据结构cv::Mat来表示图像。矩阵中每一个元素都代表一个像素,对于灰度图像,像素用8位无符号数,0表示黑色,255表示白色。对于彩色像素而言,每个像素需要三位这样的8位无符号数来表示,即三个通道(R,G,B),矩阵则依次存储一个像素的三个通道的值,然后再存储下一个像素点。
cv::Mat中,成员变量cols代表图像的宽度(图像的列数),成员变量rows代表图像的高度(图像的行数),step代表以字节为单位的图像的有效宽度,elemSize返回像素的大小,像素的大小 = 颜色大小(字节)*通道数,比如三通道short型矩阵(CV_16SC3)的大小为2*3 = 6,像素的channels方法返回图像的通道数,total函数返回图像的像素数。
闲话少说直接介绍几种读取方式:
RGB图像的颜色数目是256*256*256,本文对图像进行量化,缩减颜色数目到256的1/8(即32*32*32)为目标,分别利用一下几种方法实现,比较几种方法的安全和效率。
1.ptr遍历图像
cv::Mat中提供ptr函数访问任意一行像素的首地址,特别方便图像的一行一行的横向访问,如果需要一列一列的纵向访问图像,就稍微麻烦一点。但是ptr访问效率比较高,程序也比较安全,有越界判断。
也可以使用:
2.使用迭代器遍历图像
cv::Mat 同样有标准模板库(STL),可以使用迭代器访问数据。
用迭代器来遍历图像像素,可简化过程降低出错的机会,比较安全,不过效率较低;如果想避免修改输入图像实例cv::Mat,可采用const_iterator。iterator有两种调用方法,cv::MatIterator_<cv::Vec3b> it;cv::Mat_<cv::Vec3b>::iterator it;中间cv::Vec3b是因为图像是彩色图像,3通道,cv::Vec3b可以代表一个像素。
3.at方法遍历
cv::Mat也是向量,可以使at方法取值,使用调用方法image.at<cv::Vec3b>(j,i),at方法方便,直接给i,j赋值就可以随意访问图像中任何一个像素,其中j表示第j行,i表示该行第i个像素。但是at方法效率是这3中访问方法中最慢的一个,所以如果遍历图像或者访问像素比较多时,建议不要使用这个方法,毕竟程序的效率还是比程序的可读性要重要的。下面是完整的调用方法,其运行时间在下面会介绍。
4.row(i),col(i)
cv::Mat提供image.row(i),和image.col(j)对图像整行和整列进行处理,处理比较方便,因为很少遇到,所以就没有进行效率比较
程序代码如下(三通道):
5.高效率图像遍历循环
对于迭代的for循环,外面一层的循环次数越少速度越快,同样是cols*rows*channels()次循环,使用nc = cols,nl = rows*channels(),与使用nc = cols*rows*channels,nl = 1,以及nc = cols,nl = rows,for函数最里层运行三次颜色的处理。这三种方法最快的是第二种,第三种其次,最慢的是第一种.
6.位运算代替乘法和除法
运行时间比较,以测试图片为例,(Debug模式下的时间)
ptr函数的两种方法的时间:using .ptr and [] = 3.50202ms
using .ptr and * ++ = 3.26124ms
迭代器方法:
using Mat_ iterator = 143.06ms
at方法的运行时间:
using at = 252.779ms
高效率迭代方法:
using .ptr and * ++ and bitwise (continuous) = 2.68335ms
位运算方法:
using .ptr and * ++ and bitwise =2.59823ms
using .ptr and * ++ and modulo =3.78029ms
using .ptr and * ++ and bitwise =2.59823ms
using direct pointer arithmetic =2.57317ms
using .ptr and * ++ and bitwise with image.cols * image.channels() =22.864ms
using Mat_ iterator and bitwise =139.92ms
using MatIterator_ =185.996ms
using .ptr and * ++ and bitwise (continuous+channels) =2.11271ms
using input/output images =2.97717ms
using overloaded operators =2.7237ms
源图像:
量化处理结果 image1:
量化处理后的结果 image2:
附:OpenCV数据类型列表
| class | cv::_InputArray |
| This is the proxy class for passing read-only input arrays into OpenCV functions. More... | |
| class | cv::_InputOutputArray |
| class | cv::_OutputArray |
| This type is very similar to InputArray except that it is used for input/output and output function parameters. More... | |
| class | cv::Algorithm |
| This is a base class for all more or less complex algorithms in OpenCV. More... | |
| class | cv::Complex< _Tp > |
| A complex number class. More... | |
| class | cv::DataDepth< _Tp > |
| A helper class for cv::DataType. More... | |
| class | cv::DataType< _Tp > |
| Template "trait" class for OpenCV primitive data types. More... | |
| class | cv::DMatch |
| Class for matching keypoint descriptors. More... | |
| class | cv::Formatted |
| class | cv::Formatter |
| class | cv::KeyPoint |
| Data structure for salient point detectors. More... | |
| class | cv::Mat |
| n-dimensional dense array class More... | |
| class | cv::Mat_< _Tp > |
| Template matrix class derived from Mat. More... | |
| class | cv::MatAllocator |
| Custom array allocator. More... | |
| class | cv::MatCommaInitializer_< _Tp > |
| Comma-separated Matrix Initializer. More... | |
| class | cv::MatConstIterator |
| class | cv::MatConstIterator_< _Tp > |
| Matrix read-only iterator. More... | |
| class | cv::MatExpr |
| Matrix expression representation. More... | |
| class | cv::MatIterator_< _Tp > |
| Matrix read-write iterator. More... | |
| class | cv::MatOp |
| struct | cv::MatSize |
| struct | cv::MatStep |
| class | cv::Matx< _Tp, m, n > |
| Template class for small matrices whose type and size are known at compilation time. More... | |
| class | cv::MatxCommaInitializer< _Tp, m, n > |
| Comma-separated Matrix Initializer. More... | |
| class | cv::NAryMatIterator |
| n-ary multi-dimensional array iterator. More... | |
| struct | cv::Param |
| struct | cv::ParamType< _Tp > |
| struct | cv::ParamType< Algorithm > |
| struct | cv::ParamType< bool > |
| struct | cv::ParamType< double > |
| struct | cv::ParamType< float > |
| struct | cv::ParamType< Mat > |
| struct | cv::ParamType< std::vector< Mat > > |
| struct | cv::ParamType< String > |
| struct | cv::ParamType< uchar > |
| struct | cv::ParamType< uint64 > |
| struct | cv::ParamType< unsigned > |
| class | cv::Point3_< _Tp > |
Template class for 3D points specified by its coordinates x, y and z. More... | |
| class | cv::Point_< _Tp > |
Template class for 2D points specified by its coordinates x and y. More... | |
| struct | cv::Ptr< T > |
| Template class for smart pointers with shared ownership. More... | |
| class | cv::Range |
| Template class specifying a continuous subsequence (slice) of a sequence. More... | |
| class | cv::Rect_< _Tp > |
| Template class for 2D rectangles. More... | |
| class | cv::RotatedRect |
| The class represents rotated (i.e. not up-right) rectangles on a plane. More... | |
| class | cv::Scalar_< _Tp > |
| Template class for a 4-element vector derived from Vec. More... | |
| class | cv::Size_< _Tp > |
| Template class for specifying the size of an image or rectangle. More... | |
| class | cv::SparseMat |
| The class SparseMat represents multi-dimensional sparse numerical arrays. More... | |
| class | cv::SparseMat_< _Tp > |
| Template sparse n-dimensional array class derived from SparseMat. More... | |
| class | cv::SparseMatConstIterator |
| Read-Only Sparse Matrix Iterator. More... | |
| class | cv::SparseMatConstIterator_< _Tp > |
| Template Read-Only Sparse Matrix Iterator Class. More... | |
| class | cv::SparseMatIterator |
| Read-write Sparse Matrix Iterator. More... | |
| class | cv::SparseMatIterator_< _Tp > |
| Template Read-Write Sparse Matrix Iterator Class. More... | |
| class | cv::String |
| class | cv::TermCriteria |
| The class defining termination criteria for iterative algorithms. More... | |
| class | cv::TypeDepth< _depth > |
| class | cv::TypeDepth< CV_16S > |
| class | cv::TypeDepth< CV_16U > |
| class | cv::TypeDepth< CV_32F > |
| class | cv::TypeDepth< CV_32S > |
| class | cv::TypeDepth< CV_64F > |
| class | cv::TypeDepth< CV_8S > |
| class | cv::TypeDepth< CV_8U > |
| class | cv::UMat |
| struct | cv::UMatData |
| struct | cv::UMatDataAutoLock |
| class | cv::Vec< _Tp, cn > |
| Template class for short numerical vectors, a partial case of Matx. More... | |
| class | cv::VecCommaInitializer< _Tp, m > |
| Comma-separated Vec Initializer. More... | |
Typedefs | |
| typedef Complex< double > | cv::Complexd |
| typedef Complex< float > | cv::Complexf |
| typedef const _InputArray & | cv::InputArray |
| typedef InputArray | cv::InputArrayOfArrays |
| typedef const _InputOutputArray & | cv::InputOutputArray |
| typedef InputOutputArray | cv::InputOutputArrayOfArrays |
| typedef Mat_< uchar > | cv::Mat1b |
| typedef Mat_< double > | cv::Mat1d |
| typedef Mat_< float > | cv::Mat1f |
| typedef Mat_< int > | cv::Mat1i |
| typedef Mat_< short > | cv::Mat1s |
| typedef Mat_< ushort > | cv::Mat1w |
| typedef Mat_< Vec2b > | cv::Mat2b |
| typedef Mat_< Vec2d > | cv::Mat2d |
| typedef Mat_< Vec2f > | cv::Mat2f |
| typedef Mat_< Vec2i > | cv::Mat2i |
| typedef Mat_< Vec2s > | cv::Mat2s |
| typedef Mat_< Vec2w > | cv::Mat2w |
| typedef Mat_< Vec3b > | cv::Mat3b |
| typedef Mat_< Vec3d > | cv::Mat3d |
| typedef Mat_< Vec3f > | cv::Mat3f |
| typedef Mat_< Vec3i > | cv::Mat3i |
| typedef Mat_< Vec3s > | cv::Mat3s |
| typedef Mat_< Vec3w > | cv::Mat3w |
| typedef Mat_< Vec4b > | cv::Mat4b |
| typedef Mat_< Vec4d > | cv::Mat4d |
| typedef Mat_< Vec4f > | cv::Mat4f |
| typedef Mat_< Vec4i > | cv::Mat4i |
| typedef Mat_< Vec4s > | cv::Mat4s |
| typedef Mat_< Vec4w > | cv::Mat4w |
| typedef Matx< double, 1, 2 > | cv::Matx12d |
| typedef Matx< float, 1, 2 > | cv::Matx12f |
| typedef Matx< double, 1, 3 > | cv::Matx13d |
| typedef Matx< float, 1, 3 > | cv::Matx13f |
| typedef Matx< double, 1, 4 > | cv::Matx14d |
| typedef Matx< float, 1, 4 > | cv::Matx14f |
| typedef Matx< double, 1, 6 > | cv::Matx16d |
| typedef Matx< float, 1, 6 > | cv::Matx16f |
| typedef Matx< double, 2, 1 > | cv::Matx21d |
| typedef Matx< float, 2, 1 > | cv::Matx21f |
| typedef Matx< double, 2, 2 > | cv::Matx22d |
| typedef Matx< float, 2, 2 > | cv::Matx22f |
| typedef Matx< double, 2, 3 > | cv::Matx23d |
| typedef Matx< float, 2, 3 > | cv::Matx23f |
| typedef Matx< double, 3, 1 > | cv::Matx31d |
| typedef Matx< float, 3, 1 > | cv::Matx31f |
| typedef Matx< double, 3, 2 > | cv::Matx32d |
| typedef Matx< float, 3, 2 > | cv::Matx32f |
| typedef Matx< double, 3, 3 > | cv::Matx33d |
| typedef Matx< float, 3, 3 > | cv::Matx33f |
| typedef Matx< double, 3, 4 > | cv::Matx34d |
| typedef Matx< float, 3, 4 > | cv::Matx34f |
| typedef Matx< double, 4, 1 > | cv::Matx41d |
| typedef Matx< float, 4, 1 > | cv::Matx41f |
| typedef Matx< double, 4, 3 > | cv::Matx43d |
| typedef Matx< float, 4, 3 > | cv::Matx43f |
| typedef Matx< double, 4, 4 > | cv::Matx44d |
| typedef Matx< float, 4, 4 > | cv::Matx44f |
| typedef Matx< double, 6, 1 > | cv::Matx61d |
| typedef Matx< float, 6, 1 > | cv::Matx61f |
| typedef Matx< double, 6, 6 > | cv::Matx66d |
| typedef Matx< float, 6, 6 > | cv::Matx66f |
| typedef const _OutputArray & | cv::OutputArray |
| typedef OutputArray | cv::OutputArrayOfArrays |
| typedef Point2i | cv::Point |
| typedef Point_< double > | cv::Point2d |
| typedef Point_< float > | cv::Point2f |
| typedef Point_< int > | cv::Point2i |
| typedef Point3_< double > | cv::Point3d |
| typedef Point3_< float > | cv::Point3f |
| typedef Point3_< int > | cv::Point3i |
| typedef Rect2i | cv::Rect |
| typedef Rect_< double > | cv::Rect2d |
| typedef Rect_< float > | cv::Rect2f |
| typedef Rect_< int > | cv::Rect2i |
| typedef Scalar_< double > | cv::Scalar |
| typedef Size2i | cv::Size |
| typedef Size_< double > | cv::Size2d |
| typedef Size_< float > | cv::Size2f |
| typedef Size_< int > | cv::Size2i |
Enumerations | |
| enum | { cv::ACCESS_READ =1<<24, cv::ACCESS_WRITE =1<<25, cv::ACCESS_RW =3<<24, cv::ACCESS_MASK =ACCESS_RW, cv::ACCESS_FAST =1<<26 } |
| enum | cv::UMatUsageFlags { cv::USAGE_DEFAULT = 0, cv::USAGE_ALLOCATE_HOST_MEMORY = 1 << 0, cv::USAGE_ALLOCATE_DEVICE_MEMORY = 1 << 1, cv::USAGE_ALLOCATE_SHARED_MEMORY = 1 << 2, cv::__UMAT_USAGE_FLAGS_32BIT = 0x7fffffff } |
| Usage flags for allocator. More... | |
Functions | |
| template<typename _Tp , int m> | |
| static double | cv::determinant (const Matx< _Tp, m, m > &a) |
| template<typename T > | |
| Ptr< T > | cv::makePtr () |
| template<typename T , typename A1 > | |
| Ptr< T > | cv::makePtr (const A1 &a1) |
| template<typename T , typename A1 , typename A2 > | |
| Ptr< T > | cv::makePtr (const A1 &a1, const A2 &a2) |
| template<typename T , typename A1 , typename A2 , typename A3 > | |
| Ptr< T > | cv::makePtr (const A1 &a1, const A2 &a2, const A3 &a3) |
| template<typename T , typename A1 , typename A2 , typename A3 , typename A4 > | |
| Ptr< T > | cv::makePtr (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) |
| template<typename T , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 > | |
| Ptr< T > | cv::makePtr (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) |
| template<typename T , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 > | |
| Ptr< T > | cv::makePtr (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6) |
| template<typename T , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 > | |
| Ptr< T > | cv::makePtr (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7) |
| template<typename T , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 > | |
| Ptr< T > | cv::makePtr (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8) |
| template<typename T , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9 > | |
| Ptr< T > | cv::makePtr (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9) |
| template<typename T , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9 , typename A10 > | |
| Ptr< T > | cv::makePtr (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10) |
| InputOutputArray | cv::noArray () |
| template<typename _Tp , int m, int n> | |
| static double | cv::norm (const Matx< _Tp, m, n > &M) |
| template<typename _Tp , int m, int n> | |
| static double | cv::norm (const Matx< _Tp, m, n > &M, int normType) |
| template<typename _Tp , int cn> | |
| static Vec< _Tp, cn > | cv::normalize (const Vec< _Tp, cn > &v) |
| template<typename T > | |
| bool | cv::operator != (const Ptr< T > &ptr1, const Ptr< T > &ptr2) |
| static String & | cv::operator<< (String &out, Ptr< Formatted > fmtd) |
| static String & | cv::operator<< (String &out, const Mat &mtx) |
| template<typename T > | |
| bool | cv::operator== (const Ptr< T > &ptr1, const Ptr< T > &ptr2) |
| template<typename T > | |
| void | cv::swap (Ptr< T > &ptr1, Ptr< T > &ptr2) |
| template<typename _Tp , int m, int n> | |
| static double | cv::trace (const Matx< _Tp, m, n > &a) |
Shorter aliases for the most popular specializations of Vec<T,n> | |
| typedef Vec< uchar, 2 > | cv::Vec2b |
| typedef Vec< uchar, 3 > | cv::Vec3b |
| typedef Vec< uchar, 4 > | cv::Vec4b |
| typedef Vec< short, 2 > | cv::Vec2s |
| typedef Vec< short, 3 > | cv::Vec3s |
| typedef Vec< short, 4 > | cv::Vec4s |
| typedef Vec< ushort, 2 > | cv::Vec2w |
| typedef Vec< ushort, 3 > | cv::Vec3w |
| typedef Vec< ushort, 4 > | cv::Vec4w |
| typedef Vec< int, 2 > | cv::Vec2i |
| typedef Vec< int, 3 > | cv::Vec3i |
| typedef Vec< int, 4 > | cv::Vec4i |
| typedef Vec< int, 6 > | cv::Vec6i |
| typedef Vec< int, 8 > | cv::Vec8i |
| typedef Vec< float, 2 > | cv::Vec2f |
| typedef Vec< float, 3 > | cv::Vec3f |
| typedef Vec< float, 4 > | cv::Vec4f |
| typedef Vec< float, 6 > | cv::Vec6f |
| typedef Vec< double, 2 > | cv::Vec2d |
| typedef Vec< double, 3 > | cv::Vec3d |
| typedef Vec< double, 4 > | cv::Vec4d |
| typedef Vec< double, 6 > | cv::Vec6d |