顏色縮減 -利用指針、迭代器、動態地址實現訪問像素

為什么要使用顏色縮減

在對單通道圖像進行處理時,像素的可能值為256個,但處理多通道時,像素的處理就會相當麻煩,其實用這些顏色中具有代表性的一小部分就可以達到同樣的效果,所以顏色空間縮減就可以派上用場了。一個信道(channel)有256個不同的值(2^8=256),但是如果使用的是GRB方案,三個channel的話,顏色的數量就會變為256256256,大概是16個million這么多,這么多的顏色數量,對于計算機來說仍然是一個負擔,所以可以想一些方法來降低這些色彩數量。

顏色縮減簡單原理

公式:I_new = (I_old/10)*10; //利用int類型向下取整的特點

代碼:

/******************************顏色空間縮減*******************************************/
//顏色空間縮減:將現有的顏色空間值除以某個輸入值,以獲得較少的顏色數,比如:顏色值0-9->0,10-19->10,以此類推
//公式:I_new = (I_old/10)*10;	//利用int類型向下取整的特點
//可以將256種計算結果存入表table中
/*
int divdeWith = 10;
uchar table[256];
for(int i=0;i<256;++i)
{table[i]= divdeWith * (i/divdeWith);		//table[i]存放的是值為i的像素縮小顏色空間的結果
}
p[j]=table[p[j]];
算法步驟:
1、遍歷圖像矩陣的每一個像素
2、對像素應用上述公式
*/
/************************通過指針、迭代器、動態地址訪問元素 進行顏色縮減****************************************/
/*
訪問像素的三種方法:
1、指針訪問:C操作符[];
2、迭代器 :iterator
3、動態地址計算
*///-----------------------------------------------顏色縮減函數------------------------------------------------
void colorReduce(Mat& inputImage,Mat& outputImage,int div,int type);//-----------------------------------------------主函數------------------------------------------------
int main()
{Mat srcImage = imread("D:\\opencv_picture_test\\miku2.jpg", 2 | 4);namedWindow("原始圖", WINDOW_NORMAL);//WINDOW_NORMAL允許用戶自由伸縮窗口imshow("原始圖", srcImage);Mat dstImage;dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());	//大小類型和原圖一樣double time0 = static_cast<double>(getTickCount());	//記錄起始時間//顏色縮減colorReduce(srcImage, dstImage,128,3);//一系列處理之后time0 = ((double)getTickCount() - time0) / getTickFrequency();cout << "此方法運行時間為:" << time0 << "秒" << endl;	//輸出運行時間namedWindow("效果圖", WINDOW_NORMAL);//WINDOW_NORMAL允許用戶自由伸縮窗口imshow("效果圖", dstImage);imwrite("D:\\opencv_picture_test\\miku5.jpg", dstImage);waitKey(0);return 0;}
//-----------------------------------------------colorReduce()函數------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div, int type)
{//描述:使用指針訪問 ,很好理解,和C類似if (type == 1){outputImage = inputImage.clone();		//因為我們需要進行處理時不對原圖像產生影響,所以這里使用深復制int row_num = outputImage.rows;			//行數int col_num = outputImage.cols * outputImage.channels();			//列數*通道數 = 每一行元素的個數   灰度圖通道數為1,彩色的為3//雙重循環,遍歷所有像素值for (int i = 0;i < row_num;i++)	//行循環{uchar* data = outputImage.ptr<uchar>(i);		//獲取第i行的首地址for (int j = 0;j < col_num;j++)	//列循環{data[j] = data[j] / div * div;	//顏色縮減,也可以是其他的一些處理}}}//描述:使用迭代器訪問/*我們僅僅需要獲得圖像矩陣的begin和end,然后增加迭代直至begin到end。將*操作符添加在迭代指針前,即可訪問當前指向的內容,相比用指針直接訪問可能出現的越界問題,迭代器絕對是非常安全的*/else if (type == 2){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;(*it)[1] = (*it)[1] / div * div;(*it)[2] = (*it)[2] / div * div;//-------【處理結束】---------------}}//描述:使用動態地址運算配合at訪問else{outputImage = inputImage.clone();		//因為我們需要進行處理時不對原圖像產生影響,所以這里使用深復制int row_num = outputImage.rows;			//行數int col_num = outputImage.cols ;			//列數//雙重循環,遍歷所有像素值for (int i = 0;i < row_num;i++)	//行循環{	for (int j = 0;j < col_num;j++)	//列循環{//-------【開始處理每個像素】---------------outputImage.at<Vec3b>(i, j)[0] = outputImage.at<Vec3b>(i, j)[0] / div * div;		//B通道outputImage.at<Vec3b>(i, j)[1] = outputImage.at<Vec3b>(i, j)[1] / div * div;		//G通道outputImage.at<Vec3b>(i, j)[2] = outputImage.at<Vec3b>(i, j)[2] / div * div;		//R通道//-------【處理結束】---------------}}/*講解:成員函數at(int y,int x)可以用來存取圖像元素,但在編譯時需要知道圖像的數據類型,at方法本身不會對任何數據類型進行轉化,十分重要!!!存取彩色圖像的代碼可以寫成如下形式:image.at<Vec3b>(j,i)[channel] =value;opencv彩色圖像的順序存儲是按照BGR不是RGB!!!!*/		}
}
/****************************************************************/

處理效果:

原圖
效果圖

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378760.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378760.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378760.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

setlenient_Java日歷setLenient()方法與示例

setlenient日歷類setLenient()方法 (Calendar Class setLenient() method) setLenient() method is available in java.util package. setLenient()方法在java.util包中可用。 setLenient() method is used to set or unset lenient status of date or time interpretations. s…

PowerShell_9_零基礎自學課程_9_高級主題:靜態類和類的操作

哈哈&#xff0c;昨天弄了個ubuntu 11.10在虛擬機上運行&#xff0c;發現11.10界面非常絢麗&#xff0c;但是其需要的系統資源非常多&#xff0c;我虛擬機設定內存為512M&#xff0c;1個CPU4個核心&#xff0c; 進入以后發現根本動不了&#xff0c;因此今天我就下載了一個Fedor…

05-圖像的平滑處理(不同的濾波操作)

對圖像進行平滑處理實則就是對圖像進行濾波操作罷了 每張圖片都有若干個像素點所構成&#xff0c;濾波操作上就是將照片上的某些部分像素點進行修改從而達到平滑的效果 先展示一下原圖 import cv2 img cv2.imread(E:\Jupyter_workspace\study\data/test1.png)cv2.imshow(te…

js刪除mysql記錄_(DELETEUPDATE)修改、刪除數據記錄_MySQL

有時&#xff0c;希望除去某些記錄或更改它們的內容。DELETE 和 UPDATE 語句令我們能做到這一點。用update修改記錄UPDATE tbl_name SET 要更改的列WHERE 要更新的記錄這里的 WHERE 子句是可選的&#xff0c;因此如果不指定的話&#xff0c;表中的每個記錄都被更新。例如&#…

C++設計模式之Abstract Factory模式

一、功能   提供一個創建一系列相關或相互依賴對象的接口&#xff0c;而無需指定它們具體的類。 二、結構圖類廠最基本的結構示意圖如下&#xff1a; 在實際應用中&#xff0c;類廠模式可以擴充到很復雜的情況&#xff0c;如下圖所示&#xff1a; 三、優缺點 優點&#xff1…

數字圖像處理小練習存檔1

小練習的題目&#xff1a; 1、讀取一張圖&#xff0c;分解RGB三個通道 /************練習1**********************/ int main() {Mat img1 imread("D:\\opencv_picture_test\\miku2.jpg",2|4); //灰度圖if (img1.empty()){printf("Could not find the imag…

UIImage 壓縮

1.改變圖片大小 -(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {// Create a graphics image contextUIGraphicsBeginImageContext(newSize);// Tell the old image to draw in this new context, with the desired// new size[image drawInRect:CG…

06-對圖像進行腐蝕操作

形態學中的腐蝕操作一般處理的圖像數據為二值的 cv2.erode(img,kernel,iterations 1) kernel表示拿多大的卷積核去腐蝕 iterations表示迭代次數 可以將一些帶有毛毛的圖像去毛毛化 原圖 import cv2 import numpy as npdef show_photo(name,picture):cv2.imshow(name,picture)…

Java BufferedReader skip()方法與示例

BufferedReader類skip()方法 (BufferedReader Class skip() method) skip() method is available in java.io package. skip()方法在java.io包中可用。 skip() method is used to skip the given number of bytes of characters (n_bytes_of_char) from this BufferedReader. s…

mysql gtid binlog_MySQL之-四步實現BinLog Replication升級為GTIDs Replication的代碼實例

1、將Master和Slave服務器都設置為read-onlymysql>SET global.read_onlyON;2、將Master與Slave服務器都停下來service mysql stop3、開啟GTIDs開啟GTIDs需要在master和slave服務器上都配置gtid-mode,log-bin,log-slave-updates,enforce-gtid-consistency(在MySQL 5.6.9之前是…

【記】瑣碎

1.GIF載入問題:http://www.cnblogs.com/Lewis/archive/2011/01/17/1937066.html 2.正則分段數字&#xff1a; "12345678945612456".replace(new RegExp((\\d)(?(\\d{3})$),ig),"$1,") 其中用到了正則的后則判斷? 3.給legend設定寬度 發現IE下可以 火狐下…

spring對事務的控制 AOP

我解釋一下(* com.evan.crm.service.*.*(..))中幾個通配符的含義&#xff1a; |第一個 * —— 通配 任意返回值類型| |第二個 * —— 通配 包com.evan.crm.service下的任意class| |第三個 * —— 通配 包com.evan.crm.service下的任意class的任意方法| |第四個 .. —— 通配 方…

Opencv實現利用滑動條來調整閾值

#include <opencv2/opencv.hpp> #include <iostream>using namespace cv; using namespace std; #define WINDOW_NAME "【程序窗口】" //為窗口標題定義的宏 //*--------------------------【練習】利用滑動條來調整閾值-----------------------------…

07-對圖像進行膨脹操作

形態學中的膨脹操作即讓照片變得更大&#xff0c;與腐蝕操作互為逆運算 cv2.dilate(erosion,kernel,iterations 1) 第一個參數&#xff1a;圖像對象名稱 第二個參數&#xff1a;卷積核的大小 第三個參數&#xff1a;迭代次數 此時就可與腐蝕操作進行相結合&#xff0c;腐蝕去毛…

Java LocalDate類| parse()方法與示例

LocalDate類parse()方法 (LocalDate Class parse() method) Syntax: 句法&#xff1a; public static LocalDate parse(CharSequence c_seq);public static LocalDate parse(CharSequence c_seq, DateTimeFormatter fmtr);parse() method is available in java.time package. …

Xhtml學習筆記

1. XHTML 是什么&#xff1f; XHTML 指可擴展超文本標簽語言&#xff08;EXtensible HyperText Markup Language&#xff09;。 XHTML 的目標是取代 HTML。 XHTML 與 HTML 4.01 幾乎是相同的。 XHTML 是更嚴格更純凈的 HTML 版本。 XHTML 是作為一種 XML 應用被重新定義的 HTML…

08-開運算和閉運算

開運算和閉運算實則就是將腐蝕操作和膨脹操作結合而已&#xff0c;也就是個先后循序罷了 開運算&#xff1a;先腐蝕再膨脹 閉運算&#xff1a;先膨脹再腐蝕 cv2.morphologyEx(img_open,cv2.MORPH_OPEN,kernel) cv2.morphologyEx(img_close,cv2.MORPH_CLOSE,kernel) 第一個參數…

連通域標記——實現硬幣自動計件

前言 在自動計算圖像中有幾枚硬幣的任務中&#xff0c;分離出前景和背景后是否就可以馬上實現自動計件&#xff0c;如果可以&#xff0c;如何實現&#xff1f;如果不可以&#xff0c;為什么&#xff1f; 答案是否定的。二值化之后我們的得到的只是前景總像素的多少&#xff0c…

Storm資料匯總

一、Storm集群安裝部署 網上關于storm集群部署都大同小異。 Storm下載地址&#xff1a;http://storm-project.net Storm項目地址&#xff1a;https://github.com/nathanmarz/storm 目前的版本不支持ZooKeeper3.4.5版本&#xff0c;而支持ZooKeeper3.3.3版本。 我當時沒注意這…

getlong_Java即時類| 帶示例的getLong()方法

getlong即時類getLong()方法 (Instant Class getLong() method) getLong() method is available in java.time package. getLong()方法在java.time包中可用。 getLong() method is used to get the value as long for the given temporal field from this Instant. getLong()方…