Open CV 學習筆記:訪問圖像中像素的幾種方法

1.利用.ptr 和 []的方法

2.利用Mat_ iteractor迭代器

3.利用動態地址計算配合at 的方法

4.利用.ptr 和 * ++ 以及模操作的方法

5.利用操作符重載

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>


using namespace std;
using namespace cv;

void colorReduce1(Mat& inputImage,Mat& outputImage,int div){
	outputImage = inputImage.clone();

	int rows = inputImage.rows;
	int cols = inputImage.cols*inputImage.channels();
	
	for(int i = 0;i < rows;i++){
		uchar *data = outputImage.ptr<uchar>(i);
		for(int j = 0;j < cols;j++){
			data[j] = data[j]/div*div + div/2;
		}
	}
}

void colorReduce2(Mat &inputImage,Mat &outputImage,int div){
	outputImage = inputImage.clone();

	Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>();
	Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>();

	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;

	}
}
void colorReduce3(Mat &inputImage,Mat &outputImage,int div){
	outputImage = inputImage.clone();
	int rows = inputImage.rows;
	int cols = inputImage.cols;

	for(int i = 0;i < rows;i++){
		for(int j = 0;j < cols;j++){
			outputImage.at<Vec3b>(i,j)[0] = outputImage.at<Vec3b>(i,j)[0]/div*div + div/2;
			outputImage.at<Vec3b>(i,j)[1] = outputImage.at<Vec3b>(i,j)[1]/div*div + div/2;
			outputImage.at<Vec3b>(i,j)[2] = outputImage.at<Vec3b>(i,j)[2]/div*div + div/2;
		}
	}
}
void colorReduce4(Mat &inputImage,Mat &outputImage, int div) {

	int nl= inputImage.rows; 
	int nc= inputImage.cols * inputImage.channels(); //每行元素的總元素數量
	outputImage = inputImage.clone();
	int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
	//掩碼值
	uchar mask= 0xFF<<n; 

	for (int j=0; j<nl; j++) {

		uchar* data= outputImage.ptr<uchar>(j);

		for (int i=0; i<nc; i++) {

			*data++= *data&mask + div/2;

		}       
	}
}

void colorReduce5(Mat &inputImage,Mat &outputImage, int div){
	outputImage = inputImage.clone();

	int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
	//掩碼值
	uchar mask= 0xFF<<n; 

	//進行色彩還原
	outputImage=(outputImage&Scalar(mask,mask,mask))+Scalar(div/2,div/2,div/2);
}

int main(int argc,char **argv){
	Mat img = imread("1.jpg");
	imshow("原始圖片",img);

	Mat dst;
	dst.create(img.size(),img.type());

	//第1種方法
	double time0 = static_cast<double>(getTickCount());

	colorReduce1(img,dst,64);

	time0 = ((double)getTickCount() - time0)/getTickFrequency();
	cout<<"第1種方法的時間:"<<time0<<endl;
	imshow("處理後的圖片1",dst);

	//第2種方法
    time0 = static_cast<double>(getTickCount());

	colorReduce2(img,dst,64);

	time0 = ((double)getTickCount() - time0)/getTickFrequency();
	cout<<"第2種方法的時間:"<<time0<<endl;
	imshow("處理後的圖片2",dst);

	//第3種方法
	time0 = static_cast<double>(getTickCount());

	colorReduce3(img,dst,64);

	time0 = ((double)getTickCount() - time0)/getTickFrequency();
	cout<<"第3種方法的時間:"<<time0<<endl;
	imshow("處理後的圖片3",dst);

	//第4種方法
	time0 = static_cast<double>(getTickCount());

	colorReduce4(img,dst,64);

	time0 = ((double)getTickCount() - time0)/getTickFrequency();
	cout<<"第4種方法的時間:"<<time0<<endl;
	
	imshow("處理後的圖片4",dst);

	//第5種方法
	time0 = static_cast<double>(getTickCount());

	colorReduce5(img,dst,64);

	time0 = ((double)getTickCount() - time0)/getTickFrequency();
	cout<<"第5種方法的時間:"<<time0<<endl;

	imshow("處理後的圖片5",dst);
	waitKey(0);

	return 0;
}

運行結果:







發佈了229 篇原創文章 · 獲贊 12 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章