《OpenCV3编程入门》学习笔记5 Core组件进阶(一)访问图像中的像素
生活随笔
收集整理的這篇文章主要介紹了
《OpenCV3编程入门》学习笔记5 Core组件进阶(一)访问图像中的像素
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
第5章 Core組件進階
5.1 訪問圖像中的像素
5.1.1 圖像在內存中的存儲方式
1.圖像矩陣大小取決于通道數,矩陣中的子列個數與通道數相等。
2.如果內存足夠大,可以實現連續存儲,有助于提升圖像掃描速度,可以用isContinuous()判斷矩陣是否連續存儲。
5.1.2 顏色空間縮減
1.顏色空間縮減:將現有顏色空間值除以某個輸入值,以獲得較少的顏色數
2.如,0~9范圍的像素值為0,10~19范圍的像素值為10等
3.顏色空間縮減算法:(1)遍歷圖像矩陣的每一個像素(2)對像素應用公式int I=(I/10)*10;
4.打表:
int divideWith = 10;uchar table[256];for (int i = 0; i < 256; i++)table[i] = divideWith * (i / divideWith);
5.1.3 LUT函數:Look up table操作
1.operationsOnArrays:LUT()函數:用于批量進行圖像元素查找、掃描與操作圖像
2.使用方法:
//首先建立一個mat型用于查表Mat lookUpTable(1, 256, CV_8U);uchar* p = lookUpTable.data;for(int i = 0; i < 256; i++){p[i]= table[i];}//調用函數(I是輸入J是輸出)for(int i = 0; i < times; ++i){LUT(image, lookUpTable, dstImage);}
5.1.4 計時函數
1.getTickCount()函數:返回CPU自某個事件(如啟動電腦)以來走過的時鐘周期數
2.getTickFrequency()函數:返回CPU一秒鐘所走的時鐘周期數。
3.示例:
#include<opencv2/opencv.hpp>
#include<cstdio>
using namespace cv;
using namespace std;int main()
{//記錄起始時間double time0 = static_cast<double>(getTickCount()); //進行圖像處理操作Mat image = imread("1.jpg");Mat dstImage;blur(image, dstImage, Size(7, 7));imshow("[1]image proc", dstImage);//計算方法運行時間time0 = ((double)getTickCount() - time0) / getTickFrequency();cout << "此方法運行時間為:" << time0 << "秒" << endl;waitKey(0);return 0;
}
5.1.5 訪問圖像中像素的三類方法
1.指針訪問:C操作符[]
2.迭代器iteator
3.動態地址計算
例:將源圖像中的顏色數量由256種減少到64種
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace cv;
using namespace std;void colorReduce(Mat& inputImage, Mat& outputImage, int div);int main()
{//創建原始圖并顯示Mat srcImage = imread("1.jpg");imshow("原始圖像", srcImage);//[2]按原始圖像的參數規格來創建效果圖Mat dstImage;dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());//效果圖的大小、類型與原圖片相同//[3]記錄起始時間double time0 = static_cast<double>(getTickCount());//[4]調用顏色空間縮減函數colorReduce(srcImage, dstImage, 32);//[5]計算運行時間并輸出time0 = ((double)getTickCount() - time0) / getTickFrequency();cout << "此方法運行時間為:" << time0 << "秒" << endl;//[6]顯示效果圖imshow("效果圖", dstImage);waitKey(0);return 0;
}
//【方法一】用指針訪問像素
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{//參數準備outputImage = inputImage.clone();//復制實參到臨時變量int rowNumber = outputImage.rows;//行數int colNumber = outputImage.cols*outputImage.channels();//列數*通道數=每一行元素的個數//雙重循環,遍歷所有的像素值for (int i = 0; i < rowNumber; i++){uchar* data = outputImage.ptr<uchar>(i); //獲取第i行的首地址(Mat類的ptr函數可以得到圖像任意行的首地址)for (int j = 0; j < colNumber; j++){//處理每個像素data[j] = data[j] / div * div + div / 2;}}
}
//【方法二】用迭代器操作像素
void colorReduce(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)[1] = (*it)[1] / div * div + div / 2;}
}
//【方法三】動態地址計算
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{//參數準備outputImage = inputImage.clone();//復制實參到臨時變量int rowNumber = outputImage.rows;//行數int colNumber = outputImage.cols;//列數//存取彩色圖像像素for (int i = 0; i < rowNumber; i++){for (int j = 0; j < colNumber; j++){//對于彩色圖像,每個像素有三個部分構成,三個8位數組成的向量分別代表三個通道,Vec3b即由三個unisigned char組成的向量,image.at<Vec3b>(i,j)[channel]=value;是為圖像image第i行第j列的像素點的channel分量賦值//開始處理每個像素(成員函數at(int y,int x)可以用來存取元素,但是必須在編譯期知道圖像的數據類型)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; //紅色通道}}
}
總結
以上是生活随笔為你收集整理的《OpenCV3编程入门》学习笔记5 Core组件进阶(一)访问图像中的像素的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法设计与分析第4章 动态规划(二)【D
- 下一篇: 《OpenCV3编程入门》学习笔记5 C