OpenCV学习(2)--OpenCV中图像数据存储格式、像素点的操作、大致估算程序运行时间
OpenCV中图像数据的存储
1 void howToScanImage() { 2 /* 3 使用简单的颜色空间缩小算法来提高我们的算法性能 4 */ 5 6 /* 7 OpenCV中图像数据的存储,可以看成矩阵的形式 但每一行数据可能在内存中连在一起存储 也可能不连续。 8 9 cv::Mat::isContinuous()函数,返回bool值,判断存储是否连续。 10 这里连续的 意思是行与行之间的储存是否衔接。也就是说1*1和1*N的数据肯定是连续的,而m*n的数据就 11 是需要判断连续性的。如果数据存储是连续的,可以将图像看出一个一维数组。否则只能用二维数据方式 12 进行访问。 13 14 存储颜色 通道的顺序是BGR而不是RGB 15 */ 16 17 /* 18 cv::Mat.depth() 返回图像数据的存储格式 19 // <interface.h> 20 #define CV_8U 0 21 #define CV_8S 1 22 #define CV_16U 2 23 #define CV_16S 3 24 #define CV_32S 4 25 #define CV_32F 5 26 #define CV_64F 6 27 #define CV_16F 7 28 */ 29 //std::cout << image.depth() << std::endl; 30 }
获取某段程序的大致运行时间
1 void getTimeOfProcessRunning() { 2 // 用于返回从操作系统启动到当前所经的计时周期数 3 double t = (double)cv::getTickCount(); 4 5 std::cout << "valGetTickCount = " << t << std::endl; 6 7 // 返回CPU的频率。get Tick Frequency。这里的单位是秒,也就是一秒内重复的次数。 8 double f = (double)cv::getTickFrequency(); 9 10 std::cout << "valGetTickFrequency = " << f << std::endl; 11 12 // sleep10秒 13 Sleep(10000); 14 15 double v = ((double)cv::getTickCount() - t) / cv::getTickFrequency(); 16 std::cout << "passedTime in Seconds:" << v << std::endl; // 计算出从上一次执行getTickCount()到现在过去的时间 17 18 cv::waitKey(0); 19 }
操作图像数据中的每个像素点示例
1 void getRowsAndColsAndPixel(void) { 2 cv::Mat image = cv::imread("small.jpg", cv::IMREAD_COLOR); 3 int channels = image.channels(); 4 int nRows = image.rows; 5 int nCols = image.cols; 6 7 std::cout << "The image:" << std::endl 8 << "Rows is " << nRows << std::endl 9 << "Cols is " << nCols << std::endl; 10 11 int allCols = nCols * channels; 12 13 //if (image.isContinuous()) { 14 //std::cout << "矩阵以连续的方式存储!" << std::endl; 15 //allCols *= nRows; 16 //nRows = -1; 17 //} 18 19 for (int i = 0; i < nRows; i++) { // 画了一条竖的黑线 20 for (int j = 100; j < 201; j++) { 21 image.ptr<cv::Vec3b>(i, j)[0] = 0; // ptr 和 at 类似 访问像素点 22 image.ptr<cv::Vec3b>(i, j)[1] = 0; 23 image.ptr<cv::Vec3b>(i, j)[2] = 255; 24 } 25 } 26 27 cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE); 28 cv::imshow("Display window", image); 29 30 cv::waitKey(0); 31 return; 32 }
增强图像对比度
1 void enhanceImageContrast(const cv::Mat& image, cv::Mat& image2) { 2 // 增强图像对比度时,需要对每个像素执行以下公式 3 // I(i, j) = 5*I(i, j) - [I(i - 1, j) + I(i + 1, j) + I(i, j - 1) + I(i, j + 1)] 4 5 // 确保输入图像数据为unsigned char格式 6 CV_Assert(image.depth() == CV_8U); 7 const int nChannels = image.channels(); 8 // 创建一个与Image相同大小相同类型图像 9 image2.create(image.size(), image.type()); 10 11 for (int j = 1; j < image.rows - 1; j++) { 12 // 每次需要正在操作的行以及他的上下行的像素点 13 const uchar* previous = image.ptr<uchar>(j - 1); 14 const uchar* current = image.ptr<uchar>(j); 15 const uchar* next = image.ptr<uchar>(j + 1); 16 uchar* output = image2.ptr<uchar>(j); 17 18 for (int i = nChannels; i < nChannels * (image.cols - 1); i++) 19 *output++ = cv::saturate_cast<uchar>(5 * current[i] - current[i - nChannels] - current[i + nChannels] - previous[i] - next[i]); 20 } 21 22 // 边框上的像素点 上述的增强对比度的公式并为定义 因此全设为0 23 image2.row(0).setTo(cv::Scalar(0)); 24 image2.row(image2.rows - 1).setTo(cv::Scalar(0)); 25 image2.col(0).setTo(cv::Scalar(0)); 26 image2.col(image2.cols - 1).setTo(cv::Scalar(0)); 27 28 // 增强对比度 使用cv::filter2D() 29 //cv::Mat kernel = (cv::Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); 30 //cv::filter2D(image, image2, image.depth(), kernel); 31 // 这两行代码达成与上述相同的效果 32 }
转载请注明出处