Mat.ptr进行像素操作

下面主要通过使用Mat.ptr的两种像素操作方法和Mat.at()的像素操作方法的示例来说明时间的运行效率情况

一、使用指针操作的方法在图像上画线

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
	Mat src, gray,gray_clone;
	src = imread("../../lena.jpg");
	imshow("原图", src);
	cvtColor(src, gray, CV_BGR2GRAY);
	//复制一份灰度图
	gray_clone = gray.clone();
	imshow("灰度图", gray);
	//原图画线
	for(int i = 0;i<src.rows;i++)
		for (int j = 0; j < src.cols; j++) {
			uchar* p = src.ptr<uchar>(i, j);
			//原图是彩色图,操作三个通道修改颜色
			if (i == j) {
				p[0] = 0;
				p[1] = 255;
				p[2] = 255;
			}
		}
	imshow("原图画线", src);
	//灰度图画线方法1
	double t1 = getTickCount();
	for (int i = 0; i < gray.rows; i++)
		for (int j = 0; j < gray.cols; j++) {
			uchar* p = gray.ptr<uchar>(i, j);
			//灰度图是单通道的,只需要操作一个通道即可
			if (i == j) {
				p[0] = 255;
			}
		}
	double time_consume_1 = (getTickCount() - t1) / getTickFrequency();
	printf("灰度图画线方法1耗时:%.3f\n", time_consume_1);
	imshow("灰度图画线1", gray);

	//灰度图画线方法2
	double t2 = getTickCount();
	for (int i = 0; i < gray_clone.rows; i++) {
		uchar* p = gray_clone.ptr<uchar>(i);
		for (int j = 0; j < gray_clone.cols; j++) {
			if (i == j)
				p[j] = 255;
		}
	}
	double time_consume_2 = (getTickCount() - t2) / getTickFrequency();
	printf("灰度图画线方法2耗时:%.3f\n", time_consume_2);
	imshow("灰度图画线2", gray_clone);
	waitKey(0);
	return 0;
}

 参考链接:https://blog.csdn.net/kksc1099054857/article/details/82684678

二、两种方法取反色

1、使用Mat.at(row,col)方法

uchar gray = gray_src.at<uchar>(row, col);
gray_src.at<uchar>(row, col) = 255 - gray;

2、使用Mat.ptr方法

uchar* gray_ptr = gray_src.ptr<uchar>(row)

实现代码:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
	Mat src, gray_src;
	src = imread("../../lena.jpg");
	if (src.empty()) {
		cout << "Colud not load image..." << endl;
		return -1;
	}
	imshow("input", src);
	
	cvtColor(src, gray_src, CV_BGR2GRAY);
	imshow("src_gray", gray_src);
	
	int height = src.rows;
	int width = src.cols;

	//使用Mat.at操作实现反色
	double t1 = getTickCount();
	for(int row = 0;row<height;row++)
		for (int col = 0; col < width; col++) {
			uchar gray = gray_src.at<uchar>(row, col);
			gray_src.at<uchar>(row, col) = 255 - gray;
		}
	double time_consume_1 = (getTickCount() - t1) / getTickFrequency();
	printf("使用Mat.at操作耗时: %.3f\n", time_consume_1);

	//使用Mat.ptr指针操作实现反色
	double t2 = getTickCount();
	for (int row = 0; row < height; row++) {
		uchar* gray_ptr = gray_src.ptr<uchar>(row);
		for (int col = 0; col < width; col++) {
			gray_ptr[col] = 255 - gray_ptr[col];
		}
	}
	double time_consume_2 = (getTickCount() - t2) / getTickFrequency();
	printf("使用Mat.ptr操作耗时: %.3f\n", time_consume_2);

	//使用Mat.ptr_1指针操作实现反色
	double t3 = getTickCount();
	for (int row = 0; row < height; row++)
		for (int col = 0; col < width; col++) {
			uchar* gray_ptr_1 = gray_src.ptr<uchar>(row, col);
			gray_src.at<uchar>(row, col) = 255 - *gray_ptr_1;
		}
	double time_consume_3 = (getTickCount() - t3) / getTickFrequency();
	printf("使用Mat.ptr_1操作耗时: %.3f\n", time_consume_3);

	//实现三次反色和反色一次的效果相同
	imshow("gray_inverse", gray_src);
	waitKey(0);
	return 0;
}

从下面的输出结果可以对比三种操作方法的效率!

 三、Mat指针操作的技巧

单通道像素操作使用Mat.ptr的方法在rows循环中定义,然后在cols循环中操作耗时最短,如灰度图画线的操作和对图片进行反色操作中方法二的实现;在三通道中像素操作在cols循环内定义,然后再操作三个通道比较好理解,如用指针方法在图像上画线操作三通道的操作.

刚开始自学opencv,做一下笔记,若有理解不对的地方请多多指教.

猜你喜欢

转载自blog.csdn.net/Li_haiyu/article/details/85684305