1. 程式人生 > >遍歷影象的方法

遍歷影象的方法

遍歷影象的幾種方法

法一:

使用.ptr和[],一維陣列運算:
for (int v=0; v<image.rows; v++) 
	{
		uchar* data= image.ptr<uchar>(v);//指向每行的指標,把一行看做一個一維陣列
		for (int u=0; u<image.cols; u++) 
		{
			//-------------開始處理每個畫素-------------------
			cout<<"b="<<data[u*image.channels()]
				<<"g="<<
data[u*image.channels()+1] <<"r="<<data[u*image.channels()+2] <<endl; //-------------結束畫素處理------------------------ } //單行處理結束 }

法二:

利用Mat_ iterator:
Mat_<Vec3b>::iterator it= image.begin<Vec3b>();
Mat_<Vec3b>::iterator itend= image.
end<Vec3b>(); for ( ; it!= itend; ++it) { //-------------開始處理每個畫素------------------- cout<<"b="<<(*it)[0] <<"g="<<(*it)[1] <<"r="<<(*it)[2] <<endl; //-------------結束畫素處理------------------------ }

法三

利用動態地址計算配合at:
for (int v=0; v<image.rows;
v++) { for (int u=0; u<image.cols; u++) { //-------------開始處理每個畫素------------------- cout<<"b="<<image.at<Vec3b>(v,u)[0] <<"g="<<image.at<Vec3b>(v,u)[1] <<"r="<<image.at<Vec3b>(v,u)[2] <<endl; //-------------結束畫素處理------------------------ } //單行處理結束 }

Ex:

//--------------------------------------【程式說明】-------------------------------------------
//		程式說
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.at<Vec3b>(j,i)[0]=	 image.at<Vec3b>(j,i)[0]/div*div + div/2;
			image.at<Vec3b>(j,i)[1]=	 image.at<Vec3b>(j,i)[1]/div*div + div/2;
			image.at<Vec3b>(j,i)[2]=	 image.at<Vec3b>(j,i)[2]/div*div + div/2;
 
			//-------------結束畫素處理------------------------
 
		} //單行處理結束                 
	}
}明:《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 removed 
   or 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 v=0; v<nl; v++) 
	{
		uchar* data= image.ptr<uchar>(v);//指向每行的指標,把一行看做一個一維陣列
		for (int u=0; u<nc; u++) 
		{
			//-------------開始處理每個畫素-------------------
 
			data[u]= data[u]/div*div + div/2;
 
			//-------------結束畫素處理------------------------
			
		} //單行處理結束                  
	}
}
 
//-----------------------------------【方法二】-------------------------------------------------
//		說明:利用 .ptr 和 * ++ 
//-------------------------------------------------------------------------------------------------
void colorReduce1(Mat &image, int div=64) {
 
	int nl= image.rows; //行數
	int nc= image.cols * image.channels(); //每行元素的總元素數量=image.step

	for (int v=0; v<nl; v++) 
	{ 
		uchar* data= image.ptr<uchar>(v);
 
		for (int u=0; u<nc; u++) 
		{
 
			//-------------開始處理每個畫素-------------------
 
			*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 v=0; v<nl; v++) 
	{
		uchar* data= image.ptr<uchar>(v);
 
		for (int u=0; u<nc; u++) 
		{
 
			//-------------開始處理每個畫素-------------------
 
			int vi= *data;
			*data++= vi - vi%div + div/2;
 
			//-------------結束畫素處理------------------------
 
		} //單行處理結束                   
	}
}
 
//----------------------------------------【方法四】---------------------------------------------
//		說明:利用.ptr 和 * ++ 以及位操作
//----------------------------------------------------------------------------------------------------
void colorReduce3(Mat &image, int div=64) {
 
	int nl= image.rows; //行數
	int nc= image.cols * image.channels(); //每行元素的總元素數量
	int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
	//掩碼值
	uchar mask= 0xFF<<n; // e.g. 對於 div=16, mask= 0xF0
 
	for (int j=0; j<nl; j++) {
 
		uchar* data= image.ptr<uchar>(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_cast<int>(log(static_cast<double>(div))/log(2.0));
	int step= image.step; //有效寬度
	//掩碼值
	uchar mask= 0xFF<<n; // e.g. 對於 div=16, 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_cast<int>(log(static_cast<double>(div))/log(2.0));
	//掩碼值
	uchar mask= 0xFF<<n; // e.g. 例如div=16, mask= 0xF0
 
	for (int j=0; j<nl; j++) 
	{
 
		uchar* data= image.ptr<uchar>(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_cast<int>(log(static_cast<double>(div))/log(2.0));
	//掩碼值
	uchar mask= 0xFF<<n; // e.g. 比如div=16, mask= 0xF0
 
	for (int j=0; j<nl; j++) {
 
		uchar* data= image.ptr<uchar>(j);
 
		for (int i=0; i<nc; i++) {
 
			//-------------開始處理每個畫素-------------------
 
			*data++= *data&mask + div/2;
 
			//-------------結束畫素處理------------------------
 
		} //單行處理結束                   
	}十四種
}
 
//------------------------------------【方法八】------------------------------------------------
//		說明:利用 .ptr 和 * ++ 以及位運算 (continuous+channels)
//-------------------------------------------------------------------------------------------------
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_cast<int>(log(static_cast<double>(div))/log(2.0));
	//掩碼值
	uchar mask= 0xFF<<n; // e.g. 比如div=16, mask= 0xF0
 
	for (int j=0; j<nl; j++) {
 
		uchar* data= image.ptr<uchar>(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.begin<Vec3b>();
	Mat_<Vec3b>::iterator itend= image十四種.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;
 
		//-------------結束畫素處理------------------------
	}//單行處理結束  
}
 
//-------------------------------------【方法十】-----------------------------------------------
//		說明:利用Mat_ iterator以及位運算
//-------------------------------------------------------------------------------------------------
void colorReduce9(Mat &image, int div=64) {
 
	// div必須是2的冪
	int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
	//掩碼值
	uchar mask= 0xFF<<n; // e.g. 比如 div=16, mask= 0xF0
 
	// 獲取迭代器
	Mat_<Vec3b>::iterator it= image.begin<Vec3b>();
	Mat_<Vec3b>::iterator itend= image.end<Vec3b>();
 
	//掃描所有元素
	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)