@TOC
CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR ); enum ImreadModes { IMREAD_UNCHANGED = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). Ignore EXIF orientation. IMREAD_GRAYSCALE = 0, //!< If set, always convert image to the single channel grayscale image (codec internal conversion). IMREAD_COLOR = 1, //!< If set, always convert image to the 3 channel BGR color image. IMREAD_ANYDEPTH = 2, //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit. IMREAD_ANYCOLOR = 4, //!< If set, the image is read in any possible color format. IMREAD_LOAD_GDAL = 8, //!< If set, use the gdal driver for loading the image. IMREAD_REDUCED_GRAYSCALE_2 = 16, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/2. IMREAD_REDUCED_COLOR_2 = 17, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2. IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4. IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4. IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8. IMREAD_REDUCED_COLOR_8 = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8. IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag. };``` # 2.创建窗口 ```cpp CV_EXPORTS_W void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);
参数 | 含义 |
---|---|
winname(window name) | 窗体名 |
CV_EXPORTS_W void imshow(const String& winname, InputArray mat);
参数 | 含义 |
---|---|
winname(window name) | 窗体名 |
mat | 输入的欲显示的图片 |
CV_EXPORTS_W int waitKey(int delay = 0);
控制图片的展示时间,如设置delay=0,则表示一直展示,按SPACE停止展示
如设置delay不为0,则表示停留delay毫秒
CV_EXPORTS_W bool imwrite( const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>());``` - 参数如下 | 参数 | 含义 | | ---------- | ------------ | | filename | 保存的文件名 | | img(image) | 要保存的图片 | # 5.视频输入输出 ```cpp CV_WRAP explicit VideoCapture::VideoCapture(const String& filename, int apiPreference = CAP_ANY); CV_WRAP explicit VideoCapture::VideoCapture(const String& filename, int apiPreference, const std::vector<int>& params); CV_WRAP explicit VideoCapture::VideoCapture(int index, int apiPreference = CAP_ANY); CV_WRAP explicit VideoCapture::VideoCapture(int index, int apiPreference, const std::vector<int>& params); CV_WRAP VideoWriter::VideoWriter(const String& filename, int fourcc, double fps,Size frameSize, bool isColor = true); CV_WRAP VideoWriter::VideoWriter(const String& filename, int fourcc, double fps, const Size& frameSize,const std::vector<int>& params); CV_WRAP VideoWriter::VideoWriter(const String& filename, int apiPreference, int fourcc, double fps,const Size& frameSize, const std::vector<int>& params); //fps:帧率 //frameSize:输出视频中每一帧的尺寸
CV_WRAP static int fourcc(char c1, char c2, char c3, char c4);
代码 | 含义 |
---|---|
VideoWriter::fourcc(‘P’,‘I’,‘M’,‘1’) | MPEG-1编码,输出文件拓展名avi |
VideoWriter::fourcc(‘X’,‘V’,‘I’,‘D’) | MPEG-4编码,输出文件拓展名avi |
VideoWriter::fourcc(‘M’,‘P’,‘4’,‘V’) | 旧MPEG-4编码,输出文件拓展名avi |
VideoWriter::fourcc(‘I’,‘4’,‘2’,‘0’) | YUV编码,输出文件拓展名avi |
VideoWriter::fourcc(‘X’,‘2’,‘6’,‘4’) | MPEG-4编码,输出文件拓展名mp4 |
VideoWriter::fourcc(‘T’,‘H’,‘E’,‘O’) | ogg vorbis编码,输出文件拓展名ogv |
VideoWriter::fourcc(‘F’,L’,‘V’,‘1’) | flash video编码,输出文件拓展名flv |
首选使用的Capture API后端。如果有多个可用的读取器实现,则可以用于实施特定的读取器实现。
设置读取的摄像头编号,默认CAP_ANY=0,自动检测摄像头。多个摄像头时,使用索引0,1,2,…进行编号调用摄像头。 apiPreference = -1时单独出现窗口,选取相应编号摄像头。
VideoCapture video("demo.mp4"); Mat fps; video.read(fps); VideoWriter video_out("demo_out.avi",VideoWriter::fourcc('P','I','M','1'),30,fps.size()); while (1){ Mat fps; video>>fps; //video.read(fps); fps>>video_out; //video_out.write(fps); imshow("video",fps); waitKey(10);//控制帧率 }``` # 6.通道分离与合并 ## 6.1 分离 ### API(一) ```cpp CV_EXPORTS void split(const Mat& src, Mat* mvbegin);
参数 | 含义 |
---|---|
src(source) | 输入图像 |
mvbegin(mat vector begin) | 分离后的Mat数组的地址 |
CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv);
参数 | 含义 |
---|---|
m(mat) | 输入图像 |
mv(mat vector) | 分离后的的Mat数组,可以使用STL容器vector。 |
CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst);
参数 | 含义 |
---|---|
mv(mat vector) | 欲合并的图像数组的地址 |
count | 欲合并的图像的个数 |
dst(destination) | 输出图片 |
CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst);
参数 | 含义 |
---|---|
mv(mat vector) | 欲合并的图像数组,可以使用STL容器vector。 |
dst(destination) | 输出图片 |
CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
参数 | 含义 |
---|---|
src(source) | 源图像 |
dst(destination) | 输出图片 |
code | 转换码 |
cv::COLOR_BGR2RGB
cv::COLOR_RGB2BGR
cv::COLOR_RGBA2BGRA
cv::COLOR_BGRA2RGBA
cv::COLOR_RGB2RGBA
cv::COLOR_BGR2BGRA
cv::COLOR_RGBA2RGB
cv::COLOR_BGRA2BGR
cv::COLOR_RGB2GRAY
cv::COLOR_BGR2GRAY
cv::COLOR_RGBA2GRAY
cv::COLOR_BGRA2GRAY
cv::COLOR_GRAY2RGB
cv::COLOR_GRAY2BGR
cv::COLOR_GRAY2RGBA
cv::COLOR_GRAY2BGRA
cv::COLOR_RGB2BGR565
cv::COLOR_BGR2BGR565
cv::COLOR_BGR5652RGB
cv::COLOR_BGR5652BGR
cv::COLOR_RGBA2BGR565
cv::COLOR_BGRA2BGR565
cv::COLOR_BGR5652RGBA
cv::COLOR_BGR5652BGRA
cv::COLOR_GRAY2BGR555
cv::COLOR_BGR5552GRAY
cv::COLOR_RGB2XYZ
cv::COLOR_BGR2XYZ
cv::COLOR_XYZ2RGB
cv::COLOR_XYZ2BGR
cv::COLOR_RGB2YCrCb
cv::COLOR_BGR2YCrCb
cv::COLOR_YCrCb2RGB
cv::COLOR_YCrCb2BGR
cv::COLOR_RGB2HSV
cv::COLOR_BGR2HSV
cv::COLOR_HSV2RGB
cv::COLOR_HSV2BGR
cv::COLOR_RGB2HLS
cv::COLOR_BGR2HLS
cv::COLOR_HLS2RGB
cv::COLOR_HLS2BGR
cv::COLOR_RGB2Lab
cv::COLOR_BGR2Lab
cv::COLOR_Lab2RGB
cv::COLOR_Lab2BGR
cv::COLOR_RGB2Luv
cv::COLOR_BGR2Luv
cv::COLOR_Luv2RGB
cv::COLOR_Luv2BGR
cv::COLOR_BayerBG2RGB
cv::COLOR_BayerGB2RGB
cv::COLOR_BayerRG2RGB
cv::COLOR_BayerGR2RGB
cv::COLOR_BayerBG2BGR
cv::COLOR_BayerGB2BGR
cv::COLOR_BayerRG2BGR
cv::COLOR_BayerGR2BGR
Mat.ptr(i,j)=Mat.ptr(i,j)*a+b
a:控制对比度增益
b:控制亮度增益
Mat xuenai = imread("xuenai.jpg"); imshow("xuenai", xuenai); for(int i=0;i<xuenai.rows;i++){ for(int j=0;j<xuenai.cols;j++){ for(int k=0;k<xuenai.channels();k++) { xuenai.at<Vec3b>(i, j)[k] = saturate_cast<uchar>(xuenai.at<Vec3b>(i, j)[k] * 1.2 + 30); } } }imshow("xuenai_convertTo",xuenai); waitKey();
void Mat::convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
参数 | 含义 |
---|---|
m(mat) | 输出图片 |
rtype(result type) | 输出图片的深度,-1表示与原图一致 |
alpha | 对应系数 |
beta | 对应常数 |
Mat xuenai = imread("xuenai.jpg"); imshow("xuenai", xuenai); xuenai.convertTo(xuenai,-1,1.2,30); imshow("xuenai_convertTo",xuenai); waitKey();
可以看到效果是一样的
CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);``` - 参数如下 | 参数 | 含义 | | ----------------------- | ---------------------------------------- | | src(source1) | 输入图片1 | | alpha | src1的权重 | | src2(source2) | 输入图片2 | | beta | src2的权重 | | gamma | 额外的增量 | | dst(destination) | 输出图片 | | dtype(destination type) | 输出图片的数据类型,-1表示与输入图片一致 | # 10.图片尺寸调整 ```cpp CV_EXPORTS_W void resize( InputArray src, OutputArray dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR );``` - 参数如下 | 参数 | 含义 | | ----------------------- | ----------------------------------------------------------------------------------------- | | src(source) | 输入图片 | | dsize(destination size) | 输出图片的尺寸 | | fx | x方向(width方向)的缩放比例,如果它是0,那么它就会按照(double)dsize.width/src.cols来计算 | | fy | y方向(height方向)的缩放比例,如果它是0,那么它就会按照(double)dsize.height/src.rows来计算 | | interpolation | 插值算法的选择 | ## 10.1 插值算法(not important) ```cpp enum InterpolationFlags{ /** nearest neighbor interpolation */ INTER_NEAREST = 0, /** bilinear interpolation */ INTER_LINEAR = 1, /** bicubic interpolation */ INTER_CUBIC = 2, /** resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method. */ INTER_AREA = 3, /** Lanczos interpolation over 8x8 neighborhood */ INTER_LANCZOS4 = 4, /** Bit exact bilinear interpolation */ INTER_LINEAR_EXACT = 5, /** Bit exact nearest neighbor interpolation. This will produce same results as the nearest neighbor method in PIL, scikit-image or Matlab. */ INTER_NEAREST_EXACT = 6, /** mask for interpolation codes */ INTER_MAX = 7, /** flag, fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero */ WARP_FILL_OUTLIERS = 8, /** flag, inverse transformation For example, #linearPolar or #logPolar transforms: - flag is __not__ set: \f$dst( \rho , \phi ) = src(x,y)\f$ - flag is set: \f$dst(x,y) = src( \rho , \phi )\f$ */ WARP_INVERSE_MAP = 16};
使用注意事项:
//缩小一倍 CV_EXPORTS_W void pyrDown( InputArray src, OutputArray dst, const Size& dstsize = Size(), int borderType = BORDER_DEFAULT ); //放大一倍 CV_EXPORTS_W void pyrUp( InputArray src, OutputArray dst, const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );``` - 参数如下 | 参数 | 含义 | | ------------------------- | ------------------------------------------------------------------------------------- | | src(source) | 输入图片 | | dst(destination) | 输出图片 | | dstsize(destination size) | 输出图片的尺寸,默认自动调整 | | borderType | 边界填充方式,默认为黑边。如果没有设置dstsize,则不会出现黑边,因为已经进行了自动调整 | # 12.二值化(对灰度图) ```cpp CV_EXPORTS_W double threshold( InputArray src, OutputArray dst, double thresh, double maxval, int type );``` - 参数如下 | 参数 | 含义 | | ----------------- | -------- | | src(source) | 输入图片 | | dst(destination) | 输出图片 | | thresh(threshold) | 阈值 | | maxval(max value) | 最大值 | | type | 阈值类型 | ## 12.1 阈值类型 ```cpp enum ThresholdTypes { THRESH_BINARY = 0, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{maxval}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f] THRESH_BINARY_INV = 1, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f] THRESH_TRUNC = 2, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] THRESH_TOZERO = 3, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f] THRESH_TOZERO_INV = 4, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] THRESH_MASK = 7, THRESH_OTSU = 8, //!< flag, use Otsu algorithm to choose the optimal threshold value THRESH_TRIANGLE = 16 //!< flag, use Triangle algorithm to choose the optimal threshold value};
首先指定像素的灰度值的阈值,遍历图像中像素值,如果像素的灰度值大于这个阈值,则将这个像素设置为最大像素值(8位灰度值最大为255);若像素的灰度值小于阈值,则将该像素点像素值赋值为0。公式以及示意图如下:
首先也要指定一个阈值,不同的是在对图像进行阈值化操作时与阈值二值化相反,当像素的灰度值超过这个阈值的时候为该像素点赋值为0;当该像素的灰度值低于该阈值时赋值为最大值。公式及示意图如下:
给定像素值阈值,在图像中像素的灰度值大于该阈值的像素点被设置为该阈值,而小于该阈值的像素值保持不变。公式以及示意图如下:
与截断阈值化相反,像素点的灰度值如果大于该阈值则像素值不变,如果像素点的灰度值小于该阈值,则该像素值设置为0.公式以及示意图如下:
像素值大于阈值的像素赋值为0,而小于该阈值的像素值则保持不变,公式以及示意图如下:
inline Mat Mat::operator()( const Rect& roi ) const { return Mat(*this, roi);}
以下为实例
Mat xuenai = imread("xuenai.jpg"); resize(xuenai,xuenai,Size(1000,1000)); imshow("xuenai", xuenai); Mat tuanzi(xuenai,(Rect(0,0,500,1000))); imshow("tuanzi",tuanzi); waitKey();
Mat::Mat(const Mat& m, const Rect& roi);
以下为实例
Mat xuenai = imread("xuenai.jpg"); resize(xuenai,xuenai,Size(1000,1000)); imshow("xuenai", xuenai); Mat tuanzi(xuenai(Rect(0,0,500,1000))); imshow("tuanzi",tuanzi); waitKey();
template<typename _Tp> inline Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) : x(_x), y(_y), width(_width), height(_height) {} template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz) : x(org.x), y(org.y), width(sz.width), height(sz.height) {} template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2) { x = std::min(pt1.x, pt2.x); y = std::min(pt1.y, pt2.y); width = std::max(pt1.x, pt2.x) - x; height = std::max(pt1.y, pt2.y) - y;}
CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode);
参数 | 含义 |
---|---|
src(source) | 输入图片 |
dst(destination) | 输出图片 |
flipCode | 翻转类型,参见下表 |
flipCode 可选值 | 含义 |
---|---|
flipcode==0 | 上下翻转 |
flipcod>0 | 左右翻转 |
flipcode<0 | 上下加左右翻转,等价于旋转180° |
Mat xuenai = imread("xuenai.jpg"); imshow("xuenai", xuenai); Mat xuenai_flip(xuenai.size(), xuenai.type()); flip(xuenai, xuenai_flip, 0); imshow("xuenai_flip", xuenai_flip); waitKet();
CV_EXPORTS_W void rotate(InputArray src, OutputArray dst, int rotateCode); enum RotateFlags { ROTATE_90_CLOCKWISE = 0, //!<Rotate 90 degrees clockwise ROTATE_180 = 1, //!<Rotate 180 degrees clockwise ROTATE_90_COUNTERCLOCKWISE = 2, //!<Rotate 270 degrees clockwise};
参数 | 含义 |
---|---|
src(source) | 输入图片 |
dst(destination) | 输出图片 |
rotateCode | 旋转类型 |
Mat xuenai = imread("xuenai.jpg"); imshow("xuenai", xuenai); Mat xuenai_rotate(xuenai.size(), xuenai.type()); rotate(xuenai, xuenai_rotate, ROTATE_180); imshow("xuenai_rotate", xuenai_rotate); waitKet();
CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar());``` - 参数如下 | 参数 | 含义 | | ----------------------- | ---------------------------------------------------------------------- | | src(source) | 输入图片 | | dst(destination) | 输出图片 | | M | 变换矩阵 | | dsize(destination size) | 输出图片的尺寸,**若不对输出图片的尺寸进行调整,那么很可能会出现黑边** | | flags | 插值算法 | | borderMode | 边界外推法 | | borderValue | 填充边界的值 | ## 15.2 平移 - 只需将变换矩阵M设置成如下形式: ```cpp float delta_x=200,delta_y=200; float M_values[]={1,0,delta_x, 0,1,delta_y};Mat M(Size(3,2),CV_32F,M_values);
delta_x:x方向上的偏移量
delta_y:y方向上的偏移量
M_values:必须是浮点类型的数组对象
M:必须是CV_32F,不能用逗号式分隔创建
Mat xuenai = imread("xuenai.jpg"); imshow("xuenai",xuenai); double M_values[]={1,0,200, 0,1,200};Mat M(Size(3,2), CV_64F,M_values); Mat xuenai_shift(xuenai.size(),xuenai.type()); warpAffine(xuenai,xuenai_shift,M,xuenai.size()); imshow("xuenai_shift",xuenai_shift); waitKet();
inline Mat getRotationMatrix2D(Point2f center, double angle, double scale) { return Mat(getRotationMatrix2D_(center, angle, scale), true);}
参数 | 含义 |
---|---|
center | 旋转中心点的坐标 |
angle | 逆时针偏角 |
scale | 生成图与原图之比 |
Mat xuenai = imread("xuenai.jpg"); imshow("xuenai", xuenai); Mat M= getRotationMatrix2D(Point2f(xuenai.cols/2,xuenai.rows/2),45,1); Mat xuenai_rotate(xuenai.size(),xuenai.type()); warpAffine(xuenai,xuenai_rotate,M,xuenai.size()); imshow("xuenai_flip",xuenai_rotate);
CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] );
参数 | 含义 |
---|---|
src[](source[]) | 输入图片的坐标点集,含三个坐标点 |
dst[](destination[]) | 三个坐标点变换的目标位置 |
CV_EXPORTS_W void warpPerspective( InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar());``` - 参数如下 | 参数 | 含义 | | ----------------------- | ---------------------------------------------------------------------- | | src(source) | 输入图片 | | dst(destination) | 输出图片 | | M | 变换矩阵 | | dsize(destination size) | 输出图片的尺寸,**若不对输出图片的尺寸进行调整,那么很可能会出现黑边** | | flags | 插值算法 | | borderMode | 边界外推法 | | borderValue | 填充边界的值 | ### 已知变换后图片,逆推变换矩阵M ```cpp CV_EXPORTS_W Mat getPerspectiveTransform(InputArray src, InputArray dst, int solveMethod = DECOMP_LU);
参数 | 含义 |
---|---|
src(source) | 输入图片 |
dst(destination) | 输出图片 |
CV_EXPORTS Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU);
参数 | 含义 |
---|---|
src[](source[]) | 输入图片的坐标点集,含四个坐标点 |
dst[](destination[]) | 三个坐标点变换的目标位置 |
Mat origin = imread("origin.jpg"); Point2f point2F_origin[4]={Point2f (405,105),Point2f(2469,217),Point2f(2573,3489),Point2f(349,3547)}; Point2f point2F_tansform[4]={Point2f (0,0),Point2f(2500,0),Point2f(2500,3500),Point2f(0,3500)}; Mat M=getPerspectiveTransform(point2F_origin,point2F_tansform); Mat transfrom(origin.size(),origin.type()); warpPerspective(origin,transfrom,M,Size(2500,3500)); resize(origin,origin,Size(500,700)); resize(transfrom,transfrom,Size(500,700)); imshow("origin",origin); imshow("transform",transfrom);