天天看點

【opencv學習筆記】003之圖像像素基本操作(擷取像素指針、範圍處理)及掩膜操作(filter2D)詳解一、前言二、圖像像素基本操作三、全部代碼及結果展示

目錄

一、前言

二、圖像像素基本操作

1、擷取圖像像素指針

1.擷取圖像像素指針是什麼?

2.相應API

3.擷取目的

2、像素範圍處理saturate_cast

1.像素範圍處理是什麼?

2.像素範圍處理API

3、掩膜操作

1.掩膜是什麼?

2.掩膜操作是什麼?

3.掩膜操作的作用?

4.API

三、全部代碼及結果展示

1、代碼

2、運作效果圖

一、前言

欠下的總是要還的,繼續給大家更新有關于OpenCV的教程,很久沒給大家更新,希望能得到大家的諒解。

今天要講的是圖像像素比較簡單的幾個基本操作,包括圖像矩陣的掩膜操作,擷取像素的指針、圖像像素範圍處理以filter2D的介紹。

圖像處理很大程度上是對像素的處理,通過對比像素,修改像素,可以實作降噪、平滑、檢測等功能。

二、圖像像素基本操作

1、擷取圖像像素指針

1.擷取圖像像素指針是什麼?

二維圖像儲存在電腦中,大家可以了解為矩陣,一個二維數組,每個位置都會有一個像素值。

通路像素值,就是通路二維數組中某個位置的值。

2.相應API

通路的時候,我們先通路行,後通路列,通過如下方式,我們擷取行指針,索引i表示第幾行,從0開始計行數。

Mat.ptr<uchar>(int i=0) //擷取像素矩陣的指針,索引i表示第幾行,從0開始計行數。
           

我們通過行指針,可以擷取到該行的的所有點,即所有像素。

const uchar*  current= myImage.ptr<uchar>(row); //獲得目前行指針

p(row, col) =current[col]  //擷取目前像素點P(row, col)的像素值。

           

3.擷取目的

擷取到像素點,我們就可以對這個像素點進行操作,如果我們加上循環嵌套,還可以周遊所有的像素點,即對所有的像素點進行操作。

2、像素範圍處理saturate_cast<uchar>

1.像素範圍處理是什麼?

我們在設定圖像像素的灰階值或者RGB值時候,如果不了解,會随意設定,以RGB為例,他們的取值範圍是從0 到255,是以如果我們輸入範圍以外的資料,為防止程式出錯,我們需要控制範圍,保證我們輸入非法資料時候,不會導緻程式出現問題。

處理的原則如下:

如果我們輸入小于0的值,它會傳回0,

如果我們輸入大于255的值,它會傳回255,

如果我們輸入0-255之間的值,它會正常傳回。

2.像素範圍處理API

像素範圍處理的API是saturate_cast<uchar>:

saturate_cast<uchar>(-100) //傳回 0
saturate_cast<uchar>(288)  //傳回255
saturate_cast<uchar>(100)  //傳回100
           

3、掩膜操作

1.掩膜是什麼?

在講掩膜操作之前,先給大家說一下什麼是掩膜。

我們不考慮别的地方什麼是掩膜,我也不會給大家講掩膜的标準定義,我們既然說圖像的掩膜操作,那麼我們就說在圖像掩膜操作中的這個掩膜到底是什麼。

這個掩膜就是一個n*n的矩陣。通過掩膜去周遊圖像,

【opencv學習筆記】003之圖像像素基本操作(擷取像素指針、範圍處理)及掩膜操作(filter2D)詳解一、前言二、圖像像素基本操作三、全部代碼及結果展示

圖像與掩膜

2.掩膜操作是什麼?

接下來我們講掩膜操作,我們用數字模拟一個圖像,左邊是一個10*10的圖像矩陣,右邊是一個掩膜,他們兩個做操作。

首先,左邊黃色的3*3方塊與掩膜對應位置相乘,求得的值,存放在新圖像上的對應于原圖上的中心位置的中間的位置。就像下圖一樣:

下圖的操作是:

5 * 0 + 5 * (-1) + 5 * 0 + 5 * (-1) + 5 * 5 + 5 * (-1) + 5 * 0 + 5 * (-1) + 5 * 0 = 5
【opencv學習筆記】003之圖像像素基本操作(擷取像素指針、範圍處理)及掩膜操作(filter2D)詳解一、前言二、圖像像素基本操作三、全部代碼及結果展示

掩膜操作

由于圖像所有都是5,是以上面這個經過掩膜操作并沒有什麼太明顯的變化。

【opencv學習筆記】003之圖像像素基本操作(擷取像素指針、範圍處理)及掩膜操作(filter2D)詳解一、前言二、圖像像素基本操作三、全部代碼及結果展示

全部做掩膜操作

做完掩膜操作,邊上的像素是做不到的,對于不同的算法,邊上的像素做法不同,在這裡先不說,以後會給大家詳細講解。

我們再看一個示例:

【opencv學習筆記】003之圖像像素基本操作(擷取像素指針、範圍處理)及掩膜操作(filter2D)詳解一、前言二、圖像像素基本操作三、全部代碼及結果展示

全部做掩膜操作

對于外層一圈,不同算法不同,有的算法是将最外層全部設為0,有的是設為與其距離最近的像素點一緻,有的是在原圖外層加一層,這樣經過掩膜的圖像就是與原圖一樣尺寸了。

3.掩膜操作的作用?

掩膜操作實作圖像對比度調整。

4.API

掩膜操作的API是filter2D,函數原型是:

void filter2D( 
    InputArray src, 
    OutputArray dst, 
    int ddepth,                            
    InputArray kernel, 
    Point anchor = Point(-1,-1),                            
    double delta = 0, 
    int borderType = BORDER_DEFAULT 
);
           

函數參數含義如下:

(1)InputArray類型的src ,輸入圖像。

(2)OutputArray類型的dst ,輸出圖像,圖像的大小、通道數和輸入圖像相同。

(3)int類型的ddepth,目标圖像的所需深度。

(4)InputArray類型的kernel,卷積核(或者更确切地說是相關核)是一種單通道浮點矩陣;如果要将不同的核應用于不同的通道,請使用split将圖像分割成不同的顔色平面,并分别對其進行處理。。

(5)Point類型的anchor,表示錨點(即被平滑的那個點),注意他有預設值Point(-1,-1)。如果這個點坐标是負值的話,就表示取核的中心為錨點,是以預設值Point(-1,-1)表示這個錨點在核的中心。。

(6)double類型的delta,在将篩選的像素存儲到dst中之前添加到這些像素的可選值。說的有點專業了其實就是給所選的像素值添加一個值delta。

(7)int類型的borderType,用于推斷圖像外部像素的某種邊界模式。有預設值BORDER_DEFAULT。

如下面這個例子:

filter2D( src, dst, src.depth(), kernel );
           

三、全部代碼及結果展示

1、代碼

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;

int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("D:/hand.png");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	
	
	/*
	int cols = (src.cols-1) * src.channels();
	int offsetx = src.channels();
	int rows = src.rows;

	dst = Mat::zeros(src.size(), src.type());
	for (int row = 1; row < (rows - 1); row++) {
		const uchar* previous = src.ptr<uchar>(row - 1);
		const uchar* current = src.ptr<uchar>(row);
		const uchar* next = src.ptr<uchar>(row + 1);
		uchar* output = dst.ptr<uchar>(row);
		for (int col = offsetx; col < cols; col++) {
			output[col] = saturate_cast<uchar>(5 * current[col] - (current[col- offsetx] + current[col+ offsetx] + previous[col] + next[col]));
		}
	}
	*/
	double t = getTickCount();
	Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	filter2D(src, dst, src.depth(), kernel);
	double timeconsume = (getTickCount() - t) / getTickFrequency();
	printf("tim consume %.2f\n", timeconsume);


	imshow("input image", src);
	imshow("contrast image demo", dst);

	waitKey(0);
	return 0;
}
           

2、運作效果圖

【opencv學習筆記】003之圖像像素基本操作(擷取像素指針、範圍處理)及掩膜操作(filter2D)詳解一、前言二、圖像像素基本操作三、全部代碼及結果展示

原圖

【opencv學習筆記】003之圖像像素基本操作(擷取像素指針、範圍處理)及掩膜操作(filter2D)詳解一、前言二、圖像像素基本操作三、全部代碼及結果展示

掩膜操作後的圖像

今天的内容就講到這裡啦,有什麼問題,大家可以在下面留言哦!

繼續閱讀