OpenCV 之 數字圖像 -开发者知识库

OpenCV 之 數字圖像 -开发者知识库,第1张

1  數字圖像

   數字圖像可看作一個數值矩陣, 其中的每個元素代表一個像素點,如下圖所示:

   OpenCV 之 數字圖像 -开发者知识库,第2张   

 

2  存儲

  M 行 N 列圖像的存儲位數: b = M * N * k   ( L=2k, l ∈ [0, L-1], l 為灰度值 )

2.1  灰度圖

    OpenCV 中,灰度圖的存儲形式如下:

    OpenCV 之 數字圖像 -开发者知识库,第3张

2.2  RGB圖像

    OpenCV中,RGB圖像以 BGR 的順序存儲,如下:

    OpenCV 之 數字圖像 -开发者知识库,第4张

2.3  Mat 類

  Mat = 矩陣頭 指針(指向包含像素值的矩陣),其有如下特點:

  1)  矩陣頭包含矩陣大小,存儲函數,存儲地址等信息

  2)  使用 OpenCV 的接口函數,無需考慮內存管理

  3)  執行賦值算子 “=” 或 拷貝構造函數時,僅僅復制矩陣頭 (matrix header)

  4)  圖像矩陣的復制,應該使用 clone() 和 copyTo() 函數

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

using namespace std;
using namespace cv;

int main(int,char**)
{
// 1) 構造函數
Mat M(2,2, CV_8UC3, Scalar(0,0,255));
cout
<< "M = " << endl << " " << M << endl << endl;

// 2) create 函數
M.create(4,4, CV_8UC(2));
cout
<< "M = "<< endl << " " << M << endl << endl;

// 3) 多維矩陣
int sz[3] = {2,2,2};
Mat L(
3,sz, CV_8UC(1), Scalar::all(0));

// 4) MATLAB 風格 eye, ones or zero
Mat E = Mat::eye(4, 4, CV_64F);
cout
<< "E = " << endl << " " << E << endl << endl;
Mat O
= Mat::ones(2, 2, CV_32F);
cout
<< "O = " << endl << " " << O << endl << endl;
Mat Z
= Mat::zeros(3, 3, CV_8UC1);
cout
<< "Z = " << endl << " " << Z << endl << endl;

// 5) 3x3 雙精度
Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
cout
<< "C = " << endl << " " << C << endl << endl;

//! [clone]
Mat RowClone = C.row(1).clone();
cout
<< "RowClone = " << endl << " " << RowClone << endl << endl;

// 6) 隨機值填充矩陣
Mat R = Mat(3, 2, CV_8UC3);
randu(R, Scalar::all(
0), Scalar::all(255));

// 演示輸出格式
cout << "R (default) = " << endl << R << endl << endl;
cout
<< "R (python) = " << endl << format(R, Formatter::FMT_PYTHON) << endl << endl;
cout
<< "R (numpy) = " << endl << format(R, Formatter::FMT_NUMPY ) << endl << endl;
cout
<< "R (csv) = " << endl << format(R, Formatter::FMT_CSV ) << endl << endl;
cout
<< "R (c) = " << endl << format(R, Formatter::FMT_C ) << endl << endl;

Point2f P(
5, 1);
cout
<< "Point (2D) = " << P << endl << endl;

Point3f P3f(
2, 6, 7);
cout
<< "Point (3D) = " << P3f << endl << endl;

vector
<float> v;
v.push_back((
float)CV_PI);
v.push_back(
2);
v.push_back(
3.01f);
cout
<< "Vector of floats via Mat = " << Mat(v) << endl << endl;

vector
<Point2f> vPoints(20);
for (size_t i = 0; i < vPoints.size(); i)
vPoints[i]
= Point2f((float)(i * 5), (float)(i % 7));
cout
<< "A vector of 2D Points = " << vPoints << endl << endl;
}

 

3  鄰域

    D 定義為像素點 p(x, y) 和 q(s, t)的距離

3.1  四鄰域-十字格

    D4 = |x - s| |y - t| = 1

$\quad \begin{bmatrix} 2 & 1 & 2 \\ 1 & 0 & 1 \\ 2 & 1 & 2 \end{bmatrix} $

3.2  八鄰域-田字格

     D8 = max(|x - s|, |y - t|) = 1

$\quad \begin{bmatrix} 1 & 1 & 1 \\ 1 & 0 & 1 \\ 1 & 1 & 1 \end{bmatrix} $

 

4  代碼示例 

4.1  讀圖和顯示 

  OpenCV 中,圖像讀取和顯示的函數名,和 Matlab 中的一致, 即 imread 和 imshow

#include "opencv2/highgui/highgui.hpp"
using namespace cv;

int main(int argc, char ** argv) // int main()
{
Mat img
= imread(argv[1] - 1); // Mat img = imread("E:/.../feng.jpg");
if(img.empty())
    
return -1;
namedWindow(
"Example", CV_WINDOW_AUTOSIZE);
imshow(
"Example", img);
waitKey(
0);
}

4.2  遍歷像素

4.2.1  efficient method

Mat& ScanImageAndReduceC(Mat& I, const uchar* const table)
{
// accept only char type matrices
CV_Assert(I.depth() == CV_8U);
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols * channels;
if (I.isContinuous())
{
nCols
*= nRows;
nRows
= 1;
}
int i,j;
uchar
* p;
for( i = 0; i < nRows; i)
{
p
= I.ptr<uchar>(i);
for ( j = 0; j < nCols; j)
{
p[j]
= table[p[j]];
}
}
return I;
}

 4.2.2  iterator method

Mat& ScanImageAndReduceIterator(Mat& I, const uchar* const table)
{
// accept only char type matrices
CV_Assert(I.depth() == CV_8U);
const int channels = I.channels();
switch(channels)
{
case 1:
{
MatIterator_
<uchar> it, end;
for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; it)
*it = table[*it];
break;
}
case 3:
{
MatIterator_
<Vec3b> it, end;
for( it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; it)
{
(
*it)[0] = table[(*it)[0]];
(
*it)[1] = table[(*it)[1]];
(
*it)[2] = table[(*it)[2]];
}
}
}
return I;
}

 

最佳答案:

本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复