1. 程式人生 > >我的OpenCV學習筆記(二):操作每個畫素

我的OpenCV學習筆記(二):操作每個畫素

首先推薦一本書:《OpenCV 2 Computer Vision Application Programming Cookbook》網上可以下載到這本書的英文版,貌似沒有翻譯的。這本書的特點是裡面的程式不是那種為了演示函式功能而寫的面向過程的小程式,而是用面向物件的思路寫的大程式,不過他是一步一步教你寫出來的,也不要有太大壓力。

任何影象處理演算法,都是從操作每個畫素開始的。即使你不會使用OpenCV提供的各種影象處理函式,只要你瞭解影象處理演算法的基本原理,也可以寫出具有相同功能的程式。在OpenCV中,提供了種訪問每個畫素的方法:使用at方法、使用迭代器、使用指標。

這三種方法在訪問速度上略有差異。debug模式下,這種差異非常明顯,不過在release模式下,這種差異就不太明顯了。我們通過一組程式來說明這幾種方法,程式的目的是減少影象中顏色的數量,比如原來的影象是是256中顏色,我希望將它變成64種顏色,那我只需要將原來的顏色除以4(整除)以後再乘以4就可以了。

先看主程式:

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

using namespace std;
using namespace cv;
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
int main()
{
	Mat image = imread("D:/picture/img.tif");
	imshow("源影象",image);
	Mat result;//用來儲存結果
	result.create(image.rows,image.cols,image.type());//它的大小、型別與原圖片相匹配
	double duration;
	duration = static_cast<double>(cv::getTickCount());

	colorReduce(image,result,64);

	duration = static_cast<double>(cv::getTickCount())-duration;
	duration /= cv::getTickFrequency(); // the elapsed time in m
	cout<<"time is"<<duration<<endl;
	
	imshow("顯示結果",result);
	waitKey(0);
}


主程式中呼叫colorReduce函式來完成減少顏色的工作:

下面是使用at方法的colorReduce函式,這種方法簡潔明瞭,符合大家對畫素的直觀認識。執行時間為0.334131。

void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
	outputImage = inputImage.clone();
	int rows = outputImage.rows;
	int cols = outputImage.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;
		}
	}
}

下面是使用迭代器的colorReduce函式,這種方法與STL庫的用法類似。執行時間為0.375629

void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
	outputImage = inputImage.clone();
	//模板必須指明資料型別
	Mat_<Vec3b>::iterator it = inputImage.begin<Vec3b>();
	Mat_<Vec3b>::iterator itend = inputImage.end<Vec3b>();
	//也可以通過指明cimage型別的方法不寫begin和end的型別
	Mat_<Vec3b> cimage= outputImage;
	Mat_<Vec3b>::iterator itout = cimage.begin();
	Mat_<Vec3b>::iterator itoutend = cimage.end();
	for(;it != itend;it++,itout++)
	{
		(*itout)[0] = (*it)[0]/div*div + div/2;
		(*itout)[1] = (*it)[1]/div*div + div/2;
		(*itout)[2] = (*it)[2]/div*div + div/2;
	}
}


最後是使用指標的方法,這種方法最快,但是略有點抽象。執行時間為0.00705378!

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

}


順便說一句,OpenCV中的彩色影象不是以RGB的順序存放的,而是BGR,所以程式中的outputImage.at<Vec3b>(i,j)[0]代表的是該點的B分量。同理還有(*it)[0]。

相關推薦

OpenCV學習筆記操作每個

首先推薦一本書:《OpenCV 2 Computer Vision Application Programming Cookbook》網上可以下載到這本書的英文版,貌似沒有翻譯的。這本書的特點是裡面的程式不是那種為了演示函式功能而寫的面向過程的小程式,而是用面向物件的思路寫

OpenCV學習筆記SVM+HOG實現的行人檢測

因為一個專案的需求接觸到OpenCV裡的SVM和HOG特徵演算法,根據網上的教程一個部落格,給自己準備了一個關於行人檢測demo,裡面也有一些程式碼也是參考網上的demo,這裡大致記錄下demo的程式碼和自己的遇到的一些小問題。 參考部落格/文章: HOG+SVM行人檢測 目標檢測的影象特徵

Python + OpenCV 學習筆記>>> 運算

1. 算數運算 注意:兩幅影象的畫素大小要一致 進行影象畫素之間的算術運算,首先要匯入影象,讀取其中資訊: m1 = cv.imread("/home/pi/Desktop/m1.jpg") m2 = cv.imread("/home/pi/Desktop/m2.jpg")

opencv 視覺項目學習筆記 基於 svm 和 knn 車牌識別

its ++ eas -a rect() repr poi obj std 車牌識別的屬於常見的 模式識別 ,其基本流程為下面三個步驟: 1) 分割: 檢測並檢測圖像中感興趣區域; 2)特征提取: 對字符圖像集中的每個部分進行提取; 3)分類: 判斷圖像快是不是車牌或者 每

opencv 視覺專案學習筆記 基於 svm 和 knn 車牌識別

車牌識別的屬於常見的 模式識別 ,其基本流程為下面三個步驟: 1) 分割: 檢測並檢測影象中感興趣區域; 2)特徵提取: 對字元影象集中的每個部分進行提取; 3)分類: 判斷影象快是不是車牌或者 每個車牌字元的分類。 車牌識別分為兩個步驟, 車牌檢測, 車牌識別, 都屬於模式識別。 基本結構如下: 一、車牌

的openwrt學習筆記OpenWrt 開發環境搭建

首先我們首選的OpenWrt 編譯環境是 Ubuntu,並且應儘量選擇穩定的LTS版本,而不是更高版本的。這裡我們推薦使用 Ubuntu 12.04 LTS或者Ubuntu 14.04 LTS作為編譯平臺,此平臺必須要能穩定地接入網路。我們推薦您使用以下或更高的硬體配置:

OpenCV學習筆記20提取元素的輪廓及形狀描述子

先看提取輪廓的程式碼: Mat image = imread("D:/picture/images/binaryGroup.bmp",0); if(!image.data) return -1; imshow("源影象",image); //獲取輪廓 std

javascript學習筆記定義函數、調用函數、參數、返回值、局部和全局變量

兩個 cnblogs bsp 結果 value ava ase com 調用 定義函數、調用函數、參數、返回值 關鍵字function定義函數,格式如下: function 函數名(){ 函數體 } 調用函數、參數、返回值的規則和c語言規則類似。 1 <!DOC

CSS學習筆記特性

code 背景色 左移 line tex lin 安裝 其中 cas 一、顏色特性 1. 前景色:color 用種方式指定前景色,3種方式分別是rgb顏色,#16進制編碼,顏色名稱: color: rgb(100,100,100); color: #ee3e80; col

Unity3D之Mecanim動畫系統學習筆記模型導入

leg character ... sdk ocs 物體 mat 版本 sset 我們要在Unity3D中使用上模型和動畫,需要經過下面幾個階段的制作,下面以一個人形的模型開發為準來介紹。 模型制作 模型建模(Modelling) 我們的美術在建模時一般會制作一個稱為

kubernetes學習筆記bashborad安裝配置

tag log struct recommend ide col create part describe 官方推薦方法: 連接:https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashb

python3學習筆記Python初識

區別 說明 from 學習筆記 情況 不能 col 需要 學習 一、算法 在開始認真地編程之前,首先來解釋下什麽是計算機程序設計。簡單地說,它就是告訴計算機要做什麽。計算機可以做很多事情,但是它不會自己思考,需要我們告訴它具體細節,並且使用計算機能夠理解的語言把算法告

Linux學習筆記實戰-根據微服務端口號關閉進程

java 地方 img linux學習 區分 殺死進程 項目組 cannot home 前言 現在項目組基本都用Springboot,每個服務占用一個端口號,有時需要選擇性的關閉,但在任務管理器上他們的名稱都是java.exe,無法區分,這才學以致用。 killPort.s

Guava學習筆記基礎Joiner,Objects,Splitter及Strings

nonnull obj expect null dto 字符 情況 core cte 添加Maven依賴 JoinerTest import com.google.common.base.Joiner; import org.junit.Assert; import org

安卓開發學習筆記Android Stuidio無法引用Intent來創建對象,出現cannot resolve xxx

編譯器 port stact 消失 click first 紅色 xxx font 筆者在進行安卓開發時,發現自己的代碼語法完全沒有問題。尤其是創建intent對象的時候,語法完全是正確的,但是Android Stuidio卻顯示報錯,Intent類顯示為紅色,如圖所示:

Django學習筆記使用Template讓HTML、CSS參與網頁建立

Django學習筆記(二):使用Template讓HTML、CSS參與網頁建立 通過本文章實現: 瞭解Django中Template的使用 讓HTML、CSS等參與網頁建立 利用靜態檔案應用網頁樣式 一、Template的使用 Template是Django利用渲染器將模板檔案與資料內容結合

OpenCv學習筆記—cv::Mat學習

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Javaweb學習筆記servlet初體驗、HTTP協議

目錄 1.Servlet體驗 1.1servlet的繼承體系 1.2手動開發動態web資源 1.3工具開發動態資源 2.HTTP協議 2.1概念 2.2請求資訊 2.2.1請求行 2.2.2請求頭 2.2.3空行與實體內容 2.3HttpServlet

學習筆記使用K近鄰演算法檢測Web異常操作

使用全量比較,而不是最頻繁和最不頻繁的比較。 1.資料蒐集        我們使用詞集的模型,將全部命令去重後形成一個大型向量空間,每個命令代表一個特徵,首先通過遍歷全部命令,生成對應詞集。 with open(filename) as f: fo

Spring MVC 學習筆記@RequestMapping用法詳解

一、@RequestMapping 簡介 在Spring MVC 中使用 @RequestMapping 來對映請求,也就是通過它來指定控制器可以處理哪些URL請求,相當於Servlet中在web.xml中配置 <servlet>