网站开发分工,百度小说搜索风云排行榜,crm系统开发,php完整网站开发源码1.*寻找一个相机#xff08;你手机或笔记本的摄像头即可#xff09;#xff0c;标定它的内参。你可能会用到标定板#xff0c;或者自己打印一张标定用的棋盘格。
参考我之前写过的这篇博客#xff1a;【OpenCV】 相机标定 calibrateCamera
Code来源是《学习OpenCV3》18.…1.*寻找一个相机你手机或笔记本的摄像头即可标定它的内参。你可能会用到标定板或者自己打印一张标定用的棋盘格。
参考我之前写过的这篇博客【OpenCV】 相机标定 calibrateCamera
Code来源是《学习OpenCV3》18.01的例程笔者做了注释补充Code如下
// Example 18-1. Reading a chessboard’s width and height, reading and collecting
// the requested number of views, and calibrating the camera
#include iostream
#include opencv2/opencv.hppusing std::vector;
using std::cout;
using std::cerr;
using std::endl;void help(char **argv) { // todo rewrite thiscout \n\n Example 18-1:\nReading a chessboard’s width and height,\n reading and collecting the requested number of views,\n and calibrating the camera\n\n Call:\n argv[0] board_width board_height number_of_boards if_video,_delay_between_framee_capture image_scaling_factor\n\n Example:\n argv[0] 9 6 15 500 0.5\n -- to use the checkerboard9x6.png provided\n\n * First it reads in checker boards and calibrates itself\n * Then it saves and reloads the calibration matricies\n * Then it creates an undistortion map and finally\n * It displays an undistorted image\n endl;
}int main(int argc, char *argv[]) {int n_boards 0; // will be set by input listfloat image_sf 0.5f; // image scaling factorfloat delay 1.f;int board_w 0;int board_h 0;if (argc 4 || argc 6) {cout \nERROR: Wrong number of input parameters\n;help(argv);return -1;}board_w atoi(argv[1]);board_h atoi(argv[2]);n_boards atoi(argv[3]);if (argc 4) {delay atof(argv[4]);}if (argc 5) {image_sf atof(argv[5]);}/*image_sf是一个用来缩放图像的尺度因子(scale factor)。 角点检测的稳定性 通过缩放图像可以在一定程度上增强棋盘格角点检测的稳定性。有时候一些图像处理算法对于图像的尺寸大小比较敏感通过调整图像的尺寸可以帮助算法更好地检测到棋盘格角点。提高匹配精度 调整图像的尺寸可以使棋盘格角点在缩小或放大后仍然保持一定的像素间距有助于提高匹配的准确性。这样在后续的相机标定过程中可以更准确地匹配到对应的图像坐标和三维空间坐标。加快算法速度 在某些情况下缩小图像的尺寸可以减少计算量从而加快算法的执行速度。特别是对于较大分辨率的图像通过缩小尺寸可以降低处理的复杂度提高算法的效率。*/int board_n board_w * board_h;cv::Size board_sz cv::Size(board_w, board_h);cv::VideoCapture capture(0);if (!capture.isOpened()) {cout \nCouldnt open the camera\n;help(argv);return -1;}// ALLOCATE STORAGE//vectorvectorcv::Point2f image_points;vectorvectorcv::Point3f object_points;// Capture corner views: loop until weve got n_boards successful// captures (all corners on the board are found).//double last_captured_timestamp 0;cv::Size image_size;while (image_points.size() (size_t)n_boards) {cv::Mat image0, image;capture image0;image_size image0.size();cv::resize(image0, image, cv::Size(), image_sf, image_sf, cv::INTER_LINEAR);// Find the board//vectorcv::Point2f corners;bool found cv::findChessboardCorners(image, board_sz, corners);// Draw it//drawChessboardCorners(image, board_sz, corners, found);// If we got a good board, add it to our data//double timestamp static_castdouble(clock()) / CLOCKS_PER_SEC;if (found timestamp - last_captured_timestamp 1) {last_captured_timestamp timestamp;image ^ cv::Scalar::all(255);/*代码使用了异或运算符 ^并且将图像 image 与所有像素值为255的白色 cv::Scalar 进行异或操作。换句话说这行代码将图像中所有像素值与255进行逐位异或操作实现了反转图像像素的效果。具体来说对于每个像素的每个通道如果像素值为0异或255后为255如果像素值为255异或255后为0。因此总体上就是将原图像中的亮度值取反白色变为黑色黑色变为白色实现了一种图像反色的效果。这种操作常常用于在图像处理中实现一些效果比如图像的反色展示或者图像的二值化处理。*/cv::Mat mcorners(corners);/*将存储棋盘格角点的corners向量转换为cv::Mat类型的mcorners矩阵并对矩阵中的数据进行缩放操作。具体解释如下cv::Mat mcorners(corners);: 这一行代码通过将corners向量作为参数创建了一个新的cv::Mat类型的mcorners矩阵。这将导致mcorners矩阵拥有与corners向量相同的数据内容。mcorners * (1.0 / image_sf);: 这行代码对mcorners矩阵中的所有元素进行缩放操作。具体地每个元素除以image_sf这样就实现了对角点坐标的缩放操作。这是由于之前将图像缩放了image_sf倍而角点坐标也需要相应进行缩放处理。通过这两行代码将角点坐标存储在corners向量中的数据转换为了cv::Mat类型的矩阵并对矩阵中的数据进行了缩放操作。这是为了保持角点坐标和图像坐标的一致性。*/// 后续似乎没有用到// do not copy the datamcorners * (1.0 / image_sf);// scale the corner coordinatesimage_points.push_back(corners);object_points.push_back(vectorcv::Point3f());vectorcv::Point3f opts object_points.back();opts.resize(board_n);for (int j 0; j board_n; j) {opts[j] cv::Point3f(static_castfloat(j / board_w),static_castfloat(j % board_w), 0.0f);}cout Collected our static_castuint(image_points.size()) of n_boards needed chessboard images\n endl;}cv::imshow(Calibration, image);// show in color if we did collect the imageif ((cv::waitKey(30) 255) 27)return -1;}// END COLLECTION WHILE LOOP.cv::destroyWindow(Calibration);cout \n\n*** CALIBRATING THE CAMERA...\n endl;// CALIBRATE THE CAMERA!//cv::Mat intrinsic_matrix, distortion_coeffs;double err cv::calibrateCamera(object_points, image_points, image_size, intrinsic_matrix,distortion_coeffs, cv::noArray(), cv::noArray(),cv::CALIB_ZERO_TANGENT_DIST | cv::CALIB_FIX_PRINCIPAL_POINT);/*err表示相机标定的平均重投影误差。在 OpenCV 中calibrateCamera 函数会返回相机标定的重投影误差即用标定结果对相机拍摄的图像进行重投影并计算误差的平均值。*//*一些常见的重投影误差标准范围一般标准 对于一般应用重投影误差在0.1到1像素之间可以被接受。精度要求高 对于需要高精度测量的应用重投影误差应该控制在0.1像素以下。实时应用 对于实时图像处理或运动跟踪等应用重投影误差在1到2像素之间可能是可以接受的。*/// SAVE THE INTRINSICS AND DISTORTIONScout *** DONE!\n\nReprojection error is err \nStoring Intrinsics.xml and Distortions.xml files\n\n;cv::FileStorage fs(intrinsics.xml, cv::FileStorage::WRITE);fs image_width image_size.width image_height image_size.height camera_matrix intrinsic_matrix distortion_coefficients distortion_coeffs;fs.release();// EXAMPLE OF LOADING THESE MATRICES BACK IN:fs.open(intrinsics.xml, cv::FileStorage::READ);cout \nimage width: static_castint(fs[image_width]);cout \nimage height: static_castint(fs[image_height]);cv::Mat intrinsic_matrix_loaded, distortion_coeffs_loaded;fs[camera_matrix] intrinsic_matrix_loaded;fs[distortion_coefficients] distortion_coeffs_loaded;cout \nintrinsic matrix: intrinsic_matrix_loaded;cout \ndistortion coefficients: distortion_coeffs_loaded endl;// Build the undistort map which we will use for all// subsequent frames.//cv::Mat map1, map2;cv::initUndistortRectifyMap(intrinsic_matrix_loaded, distortion_coeffs_loaded,cv::Mat(), intrinsic_matrix_loaded, image_size,CV_16SC2, map1, map2);// Just run the camera to the screen, now showing the raw and// the undistorted image.//for (;;) {cv::Mat image, image0;capture image0;if (image0.empty()) {break;}cv::remap(image0, image, map1, map2, cv::INTER_LINEAR,cv::BORDER_CONSTANT, cv::Scalar());cv::imshow(Undistorted, image);if ((cv::waitKey(30) 255) 27) {break;}}return 0;
} 2.叙述相机内参的物理意义。如果一个相机的分辨率变成两倍而其他地方不变它的内参如何变化 3.搜索特殊的相机鱼眼或全景相机的标定方法。它们与普通的针孔模型有何不同
鱼眼相机模型和普通针孔相机模型的标定流程类似但是鱼眼相机在结构上比普通相机的透镜更多引入了更大的径向畸变。
因为鱼眼相机的投影模型为了将尽可能大的场景投影到有限的图像平面内允许了相机畸变的存在。并且由于鱼眼相机的径向畸变非常严重所以鱼眼相机主要的是考虑径向畸变而忽略其余类型的畸变。
为了将尽可能大的场景投影到有限的图像平面内鱼眼相机会按照一定的投影函数来设计。根据投影函数的不同鱼眼相机的设计模型大致能被分为四种等距投影模型、等立体角投影模型、正交投影模型和体视投影模型。
总的来说就是在标定时采用的畸变模型不同。以OpenCV为例OpenCV求解相机参数分为两步1、求解焦距和偏移2、求解畸变参数。鱼眼相机与普通相机第一步大致相同但鱼眼相机标定时畸变模型一般使用五元素形式(k1k2p1p2和k3)。详细请参考【OpenCV】 相机标定 calibrateCamera和鱼眼相机成像模型以及基于OpenCV标定鱼眼镜头
笔者没有接触过全景相机请参考【计算机视觉】全景相机标定MATLAB/opencv
4.调研全局快门相机global shutter和卷帘快门相机rolling shutter的异同。它们在SLAM 中有何优缺点
全局快门相机通过整幅场景在同一时间曝光实现的CCD是全局快门。Sensor所有像素点同时收集光线同时曝光。即在曝光开始的时候Sensor开始收集光线在曝光结束的时候光线收集电路被切断。然后Sensor值读出即为一幅照片。全局快门曝光时间更短容易产生噪点。由于硬件成本帧率一般比同价位的卷帘快门低。尤其是对于抓拍高速运动的物体有劣势由于技术限制很难将巨大的数据量同时处理。
卷帘快门相机通过Sensor逐行曝光的方式实现的CMOS大多是卷帘快门。在曝光开始的时候Sensor逐行扫描逐行进行曝光直至所有像素点都被曝光。当然所有的动作在极短的时间内完成。不同行像元的曝光时间不同。大多数CMOS传感器采用这一快门。当物体或者相机在高速运动时会出现果冻效应。 果冻效应
用卷帘快门方式拍摄逐行扫描速度不够拍摄结果就可能出现倾斜、摇摆不定或部分曝光等情况。这种卷帘快门方式拍摄出现的现象就定义为果冻效应。
总结对于高速移动的物体来说卷帘快门容易出现扭曲现象果冻效应。用Global shutter方式拍摄假如曝光时间过长照片会产生像糊现象。而且由于技术限制很难将巨大的数据量同时处理。 5.RGB-D 相机是如何标定的以Kinect 为例需要标定哪些参数
参照GitHub - code-iai/iai_kinect2: Tools for using the Kinect One (Kinect v2) in ROS.
Kinect2由普通RGB相机、红外相机和红外投射器组成其中红外相机和红外投射器共同组成深度相机。
根据Kinect2结构所以需要标定参数比普通RGB相机多出来红外相机的相机内参和畸变参数以及普通RGB相机、红外相机的外参位姿变换矩阵和深度图的深度值校准。 故需要标定参数为 RGB相机相机内参和畸变参数 红外相机相机内参和畸变参数 RGB相机和红外相机的外参位姿变换矩阵 深度图的深度值校准 Kinect2标定原理详情请参考RGB-D相机的标定与图像配准 6.除了示例程序演示的遍历图像的方式你还能举出哪些遍历图像的方法
《OpenCV3编程入门》配套示例程序提供了14种之多。
Code如下
//--------------------------------------【程序说明】-------------------------------------------
// 程序说明《OpenCV3编程入门》OpenCV2版书本配套示例程序24
// 程序描述来自一本国外OpenCV2书籍的示例-遍历图像像素的14种方法
// 测试所用IDE版本Visual Studio 2010
// 测试所用OpenCV版本 2.4.9
// 2014年11月 Revised by 浅墨_毛星云
//------------------------------------------------------------------------------------------------/*------------------------------------------------------------------------------------------*\This file contains material supporting chapter 2 of the cookbook:Computer Vision Programming using the OpenCV Library.by Robert Laganiere, Packt Publishing, 2011.This program is free software; permission is hereby granted to use, copy, modify,and distribute this source code, or portions thereof, for any purpose, without fee,subject to the restriction that the copyright notice may not be removedor altered from any source or altered source distribution.The software is released on an as-is basis and without any warranties of any kind.In particular, the software is not guaranteed to be fault-tolerant or free from failure.The author disclaims all warranties with regard to this software, any use,and any consequent failure, is purely the responsibility of the user.Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
\*------------------------------------------------------------------------------------------*///---------------------------------【头文件、命名空间包含部分】-----------------------------
// 描述包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#include iostream
#include opencv2/core/core.hpp
#include opencv2/highgui/highgui.hpp
using namespace cv;
using namespace std;//---------------------------------【宏定义部分】---------------------------------------------
// 描述包含程序所使用宏定义
//-------------------------------------------------------------------------------------------------
#define NTESTS 14
#define NITERATIONS 20//----------------------------------------- 【方法一】-------------------------------------------
// 说明利用.ptr 和 []
//-------------------------------------------------------------------------------------------------
void colorReduce0(Mat image, int div 64) {int nl image.rows; //行数int nc image.cols * image.channels(); //每行元素的总元素数量for (int j 0; j nl; j){uchar* data image.ptruchar(j);for (int i 0; i nc; i){//-------------开始处理每个像素-------------------data[i] data[i] / div * div div / 2;//-------------结束像素处理------------------------} //单行处理结束 }
}//-----------------------------------【方法二】-------------------------------------------------
// 说明利用 .ptr 和 *
//-------------------------------------------------------------------------------------------------
void colorReduce1(Mat image, int div 64) {int nl image.rows; //行数int nc image.cols * image.channels(); //每行元素的总元素数量for (int j 0; j nl; j){uchar* data image.ptruchar(j);for (int i 0; i nc; i){//-------------开始处理每个像素-------------------*data *data / div * div div / 2;//-------------结束像素处理------------------------} //单行处理结束 }
}//-----------------------------------------【方法三】-------------------------------------------
// 说明利用.ptr 和 * 以及模操作
//-------------------------------------------------------------------------------------------------
void colorReduce2(Mat image, int div 64) {int nl image.rows; //行数int nc image.cols * image.channels(); //每行元素的总元素数量for (int j 0; j nl; j){uchar* data image.ptruchar(j);for (int i 0; i nc; i){//-------------开始处理每个像素-------------------int v *data;*data v - v % div div / 2;//-------------结束像素处理------------------------} //单行处理结束 }
}//----------------------------------------【方法四】---------------------------------------------
// 说明利用.ptr 和 * 以及位操作
//----------------------------------------------------------------------------------------------------
void colorReduce3(Mat image, int div 64) {int nl image.rows; //行数int nc image.cols * image.channels(); //每行元素的总元素数量int n static_castint(log(static_castdouble(div)) / log(2.0));//掩码值uchar mask 0xFF n; // e.g. 对于 div16, mask 0xF0for (int j 0; j nl; j) {uchar* data image.ptruchar(j);for (int i 0; i nc; i) {//------------开始处理每个像素-------------------*data *data mask div / 2;//-------------结束像素处理------------------------} //单行处理结束 }
}//----------------------------------------【方法五】----------------------------------------------
// 说明利用指针算术运算
//---------------------------------------------------------------------------------------------------
void colorReduce4(Mat image, int div 64) {int nl image.rows; //行数int nc image.cols * image.channels(); //每行元素的总元素数量int n static_castint(log(static_castdouble(div)) / log(2.0));int step image.step; //有效宽度//掩码值uchar mask 0xFF n; // e.g. 对于 div16, mask 0xF0//获取指向图像缓冲区的指针uchar* data image.data;for (int j 0; j nl; j){for (int i 0; i nc; i){//-------------开始处理每个像素-------------------*(data i) *data mask div / 2;//-------------结束像素处理------------------------} //单行处理结束 data step; // next line}
}//---------------------------------------【方法六】----------------------------------------------
// 说明利用 .ptr 和 * 以及位运算、image.cols * image.channels()
//-------------------------------------------------------------------------------------------------
void colorReduce5(Mat image, int div 64) {int nl image.rows; //行数int n static_castint(log(static_castdouble(div)) / log(2.0));//掩码值uchar mask 0xFF n; // e.g. 例如div16, mask 0xF0for (int j 0; j nl; j){uchar* data image.ptruchar(j);for (int i 0; i image.cols * image.channels(); i){//-------------开始处理每个像素-------------------*data *data mask div / 2;//-------------结束像素处理------------------------} //单行处理结束 }
}// -------------------------------------【方法七】----------------------------------------------
// 说明利用.ptr 和 * 以及位运算(continuous)
//-------------------------------------------------------------------------------------------------
void colorReduce6(Mat image, int div 64) {int nl image.rows; //行数int nc image.cols * image.channels(); //每行元素的总元素数量if (image.isContinuous()){//无填充像素nc nc * nl;nl 1; // 为一维数列}int n static_castint(log(static_castdouble(div)) / log(2.0));//掩码值uchar mask 0xFF n; // e.g. 比如div16, mask 0xF0for (int j 0; j nl; j) {uchar* data image.ptruchar(j);for (int i 0; i nc; i) {//-------------开始处理每个像素-------------------*data *data mask div / 2;//-------------结束像素处理------------------------} //单行处理结束 }
}//------------------------------------【方法八】------------------------------------------------
// 说明利用 .ptr 和 * 以及位运算 (continuouschannels)
//-------------------------------------------------------------------------------------------------
void colorReduce7(Mat image, int div 64) {int nl image.rows; //行数int nc image.cols; //列数if (image.isContinuous()){//无填充像素nc nc * nl;nl 1; // 为一维数组}int n static_castint(log(static_castdouble(div)) / log(2.0));//掩码值uchar mask 0xFF n; // e.g. 比如div16, mask 0xF0for (int j 0; j nl; j) {uchar* data image.ptruchar(j);for (int i 0; i nc; i) {//-------------开始处理每个像素-------------------*data *data mask div / 2;*data *data mask div / 2;*data *data mask div / 2;//-------------结束像素处理------------------------} //单行处理结束 }
}// -----------------------------------【方法九】 ------------------------------------------------
// 说明利用Mat_ iterator
//-------------------------------------------------------------------------------------------------
void colorReduce8(Mat image, int div 64) {//获取迭代器Mat_Vec3b::iterator it image.beginVec3b();Mat_Vec3b::iterator itend image.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;//-------------结束像素处理------------------------}//单行处理结束
}//-------------------------------------【方法十】-----------------------------------------------
// 说明利用Mat_ iterator以及位运算
//-------------------------------------------------------------------------------------------------
void colorReduce9(Mat image, int div 64) {// div必须是2的幂int n static_castint(log(static_castdouble(div)) / log(2.0));//掩码值uchar mask 0xFF n; // e.g. 比如 div16, mask 0xF0// 获取迭代器Mat_Vec3b::iterator it image.beginVec3b();Mat_Vec3b::iterator itend image.endVec3b();//扫描所有元素for (; it ! itend; it){//-------------开始处理每个像素-------------------(*it)[0] (*it)[0] mask div / 2;(*it)[1] (*it)[1] mask div / 2;(*it)[2] (*it)[2] mask div / 2;//-------------结束像素处理------------------------}//单行处理结束
}//------------------------------------【方法十一】---------------------------------------------
// 说明利用Mat Iterator_
//-------------------------------------------------------------------------------------------------
void colorReduce10(Mat image, int div 64) {//获取迭代器Mat_Vec3b cimage image;Mat_Vec3b::iterator it cimage.begin();Mat_Vec3b::iterator itend cimage.end();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;//-------------结束像素处理------------------------}
}//--------------------------------------【方法十二】--------------------------------------------
// 说明利用动态地址计算配合at
//-------------------------------------------------------------------------------------------------
void colorReduce11(Mat image, int div 64) {int nl image.rows; //行数int nc image.cols; //列数for (int j 0; j nl; j){for (int i 0; i nc; i){//-------------开始处理每个像素-------------------image.atVec3b(j, i)[0] image.atVec3b(j, i)[0] / div * div div / 2;image.atVec3b(j, i)[1] image.atVec3b(j, i)[1] / div * div div / 2;image.atVec3b(j, i)[2] image.atVec3b(j, i)[2] / div * div div / 2;//-------------结束像素处理------------------------} //单行处理结束 }
}//----------------------------------【方法十三】-----------------------------------------------
// 说明利用图像的输入与输出
//-------------------------------------------------------------------------------------------------
void colorReduce12(const Mat image, //输入图像Mat result, // 输出图像int div 64) {int nl image.rows; //行数int nc image.cols; //列数//准备好初始化后的Mat给输出图像result.create(image.rows, image.cols, image.type());//创建无像素填充的图像nc nc * nl;nl 1; //单维数组int n static_castint(log(static_castdouble(div)) / log(2.0));//掩码值uchar mask 0xFF n; // e.g.比如div16, mask 0xF0for (int j 0; j nl; j) {uchar* data result.ptruchar(j);const uchar* idata image.ptruchar(j);for (int i 0; i nc; i) {//-------------开始处理每个像素-------------------*data (*idata) mask div / 2;*data (*idata) mask div / 2;*data (*idata) mask div / 2;//-------------结束像素处理------------------------} //单行处理结束 }
}//--------------------------------------【方法十四】-------------------------------------------
// 说明利用操作符重载
//-------------------------------------------------------------------------------------------------
void colorReduce13(Mat image, int div 64) {int n static_castint(log(static_castdouble(div)) / log(2.0));//掩码值uchar mask 0xFF n; // e.g. 比如div16, mask 0xF0//进行色彩还原image (image Scalar(mask, mask, mask)) Scalar(div / 2, div / 2, div / 2);
}//-----------------------------------【ShowHelpText( )函数】-----------------------------
// 描述输出一些帮助信息
//----------------------------------------------------------------------------------------------
void ShowHelpText()
{//输出欢迎信息和OpenCV版本printf(\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书\n);printf(\n\n\t\t\t此为本书OpenCV2版的第24个配套示例程序\n);printf(\n\n\t\t\t 当前使用的OpenCV版本为 CV_VERSION);printf(\n\n ----------------------------------------------------------------------------\n);printf(\n\n正在进行存取操作请稍等……\n\n);
}//-----------------------------------【main( )函数】--------------------------------------------
// 描述控制台应用程序的入口函数我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main()
{int64 t[NTESTS], tinit;Mat image0;Mat image1;Mat image2;//system(color 4F);ShowHelpText();image0 imread(1.png);if (!image0.data)return 0;//时间值设为0for (int i 0; i NTESTS; i)t[i] 0;// 多次重复测试int n NITERATIONS;for (int k 0; k n; k){cout k of n endl;image1 imread(1.png);//【方法一】利用.ptr 和 []tinit getTickCount();colorReduce0(image1);t[0] getTickCount() - tinit;//【方法二】利用 .ptr 和 * image1 imread(1.png);tinit getTickCount();colorReduce1(image1);t[1] getTickCount() - tinit;//【方法三】利用.ptr 和 * 以及模操作image1 imread(1.png);tinit getTickCount();colorReduce2(image1);t[2] getTickCount() - tinit;//【方法四】 利用.ptr 和 * 以及位操作image1 imread(1.png);tinit getTickCount();colorReduce3(image1);t[3] getTickCount() - tinit;//【方法五】 利用指针的算术运算image1 imread(1.png);tinit getTickCount();colorReduce4(image1);t[4] getTickCount() - tinit;//【方法六】利用 .ptr 和 * 以及位运算、image.cols * image.channels()image1 imread(1.png);tinit getTickCount();colorReduce5(image1);t[5] getTickCount() - tinit;//【方法七】利用.ptr 和 * 以及位运算(continuous)image1 imread(1.png);tinit getTickCount();colorReduce6(image1);t[6] getTickCount() - tinit;//【方法八】利用 .ptr 和 * 以及位运算 (continuouschannels)image1 imread(1.png);tinit getTickCount();colorReduce7(image1);t[7] getTickCount() - tinit;//【方法九】 利用Mat_ iteratorimage1 imread(1.png);tinit getTickCount();colorReduce8(image1);t[8] getTickCount() - tinit;//【方法十】 利用Mat_ iterator以及位运算image1 imread(1.png);tinit getTickCount();colorReduce9(image1);t[9] getTickCount() - tinit;//【方法十一】利用Mat Iterator_image1 imread(1.png);tinit getTickCount();colorReduce10(image1);t[10] getTickCount() - tinit;//【方法十二】 利用动态地址计算配合atimage1 imread(1.png);tinit getTickCount();colorReduce11(image1);t[11] getTickCount() - tinit;//【方法十三】 利用图像的输入与输出image1 imread(1.png);tinit getTickCount();Mat result;colorReduce12(image1, result);t[12] getTickCount() - tinit;image2 result;//【方法十四】 利用操作符重载image1 imread(1.png);tinit getTickCount();colorReduce13(image1);t[13] getTickCount() - tinit;//------------------------------}//输出图像 imshow(原始图像, image0);imshow(结果, image2);imshow(图像结果, image1);// 输出平均执行时间cout endl ------------------------------------------- endl endl;cout \n【方法一】利用.ptr 和 []的方法所用时间为 1000. * t[0] / getTickFrequency() / n ms endl;cout \n【方法二】利用 .ptr 和 * 的方法所用时间为 1000. * t[1] / getTickFrequency() / n ms endl;cout \n【方法三】利用.ptr 和 * 以及模操作的方法所用时间为 1000. * t[2] / getTickFrequency() / n ms endl;cout \n【方法四】利用.ptr 和 * 以及位操作的方法所用时间为 1000. * t[3] / getTickFrequency() / n ms endl;cout \n【方法五】利用指针算术运算的方法所用时间为 1000. * t[4] / getTickFrequency() / n ms endl;cout \n【方法六】利用 .ptr 和 * 以及位运算、channels()的方法所用时间为 1000. * t[5] / getTickFrequency() / n ms endl;cout \n【方法七】利用.ptr 和 * 以及位运算(continuous)的方法所用时间为 1000. * t[6] / getTickFrequency() / n ms endl;cout \n【方法八】利用 .ptr 和 * 以及位运算 (continuouschannels)的方法所用时间为 1000. * t[7] / getTickFrequency() / n ms endl;cout \n【方法九】利用Mat_ iterator 的方法所用时间为 1000. * t[8] / getTickFrequency() / n ms endl;cout \n【方法十】利用Mat_ iterator以及位运算的方法所用时间为 1000. * t[9] / getTickFrequency() / n ms endl;cout \n【方法十一】利用Mat Iterator_的方法所用时间为 1000. * t[10] / getTickFrequency() / n ms endl;cout \n【方法十二】利用动态地址计算配合at 的方法所用时间为 1000. * t[11] / getTickFrequency() / n ms endl;cout \n【方法十三】利用图像的输入与输出的方法所用时间为 1000. * t[12] / getTickFrequency() / n ms endl;cout \n【方法十四】利用操作符重载的方法所用时间为 1000. * t[13] / getTickFrequency() / n ms endl;waitKey();return 0;
} 运行结果
其中方法5利用指针算术、方法八利用 .ptr 和* 以及位运算(continuouschannels)以及方法14利用操作符重载的方法最佳。
7.学习OpenCV基本用法
推荐两本学习OpenCV基本用法参考书
1、《学习OpenCV3》
2、《OpenCV3编程入门》