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 }
原文地址:https://www.cnblogs.com/lnlin/p/13730685.html