第五天:opencv-訪問圖像像素

圖像處理通常是對圖像像素進行算法分析,所以瞭解像素的存儲方式是尤爲重要的。

(1)、圖像在內存中的存儲方式

圖像矩陣的大小取決於所用的顏色模型(或者說通道數),灰度圖像矩陣每行每列對應一個元素也就是灰度值,而彩色圖像矩陣每行每列對應BGR三種元素的值。

(2)、訪問圖像像素的方法

a. 動態地址計算訪問

eg:

	///動態地址訪問
	Mat img = imread("1.jpg");
	imshow("src", img);
	Mat dst = img.clone();
	int rowNumber = img.rows;  //獲取行數
	int colNumber = img.cols;  //獲取列數
	for(int i = 0; i<rowNumber; i++)
	{
		for(int j = 0; j<colNumber; j++)
		{
			dst.at<Vec3b>(i, j)[0] = 255;  //藍色通道
			dst.at<Vec3b>(i, j)[1] = 0;  //綠色通道
			dst.at<Vec3b>(i, j)[2] = 0;  //紅色通道
		}
	}
	imshow("dst", dst);
	waitKey(0);

成員函數at用來讀取像素,<Vec3b>表示一個uchar[3]類型的數組,如果是灰度圖像用at<uchar>(i,j)=255的形式訪問。


b. 指針訪問

eg:

	///指針訪問
	Mat img = imread("1.jpg");
	imshow("src", img);
	Mat dst = img.clone();
	int rowNumber = img.rows;  //獲取行數
	int colNumber = img.cols * img.channels();  //獲取每一行的元素
	for(int i = 0; i<rowNumber; i++)
	{
		uchar* data = dst.ptr<uchar>(i);  //獲取每一行首地址
		for(int j = 0; j<colNumber; j++)
		{
			switch(j % 3)
			{
				case 0:  //藍色通道
					data[j] = 255;
					break;
				case 1:  //綠色通道
					data[j] = 0;
					break;
				case 2:  //紅色通道
					data[j] = 255;
					break;
			}
		}
	}
	imshow("dst", dst);
	waitKey(0);

Mat類提供了ptr函數可以得到圖像任意行的首地址

(3)、實現一個圖片減色和雪花的效果

eg:

#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;

void main()
{
	///減色算法
	//Mat img = imread("1.jpg");
	//imshow("src", img);
	//Mat dst = img.clone();
	//int rowNumber = img.rows;  //獲取行數
	//int colNumber = img.cols * img.channels();  //獲取每一行的元素
	//for(int i = 0; i<rowNumber; i++)
	//{
	//	uchar* data = dst.ptr<uchar>(i);  //獲取每一行首地址
	//	for(int j = 0; j<colNumber; j++)
	//	{
	//		switch(j % 3)
	//		{
	//			case 0:  //藍色通道
	//				data[j] = 64 * 64 + 64/2; //一個減色算法
	//				break;
	//			case 1:  //綠色通道
	//				data[j] = 64 * 64 + 64/2;
	//				break;
	//			case 2:  //紅色通道
	//				data[j] = 64 * 64 + 64/2;
	//				break;
	//		}
	//	}
	//}
	//imshow("dst", dst);
	//waitKey(0);

	///雪花效果
	Mat img = imread("1.jpg");
	imshow("src", img);
	Mat dst = img.clone();
	int rowNumber = img.rows;  //獲取行數
	int colNumber = img.cols;  //獲取列數
	int i, j;
	for(int k = 0; k< 2000; k++)
	{
		i = rand() % rowNumber; 
		j = rand() % colNumber; 
		dst.at<Vec3b>(i, j)[0] = 255;  //藍色通道
		dst.at<Vec3b>(i, j)[1] = 255;  //綠色通道
		dst.at<Vec3b>(i, j)[2] = 255;  //紅色通道
	}

	imshow("dst", dst);
	waitKey(0);
}


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