1、訪問圖像像素
1)灰度圖像
2)彩色圖像
OpenCV中的顏色順序是BGR而不是RGB。
訪問圖像的像素在OpenCV中就是訪問Mat矩陣,常用的有三種方法。
- at定位符訪問
Mat數據結構,操作灰度圖像像素點:
int gray_value = (int) image.at<uchar>(i , j) ;
操作彩色圖像像素點:
int color_value = (int) image.at<Vec3b>(i , j) [k];
- 指針訪問
for (int i = 0; i < mat.rows; i++) { uchar* row = mat.ptr<uchar>(i); // 行指針 for (int j = 0; j < mat.cols; j++) // 遍歷每一行 { row[j] = (uchar)((j / 5) * 10); } }
- 迭代器iterator訪問
Mat_<Vec3b>::iterator it = M.begin<Vec3b>();//初始位置的迭代器 Mat_<Vec3b>::iterator itend = M.end<Vec3b>();//終止位置的迭代器 for (; it != itend; it++) { //處理BGR三個通道 (*it)[0] = 182;//B (*it)[1] = 194;//G (*it)[2] = 154;//R }
2、圖像亮度、對比度調節
圖像亮度調節可以等效為圖像的像素操作。如下面公式是一個線性的亮度調節。
g(x)=a*f(x) + b
其中:
g(x):處理后的圖像
f(x):輸入圖像
a:增益(放大倍數),用來控制圖像的對比度
b:偏置,用控制圖像的亮度
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic4.bmp", IMREAD_GRAYSCALE); Mat M2 = Mat(M.rows, M.cols, CV_8UC1); cout << M.channels() << endl; cout << M.rows<<","<<M.cols << endl; float a = 0.5; float b = 10; for (int i = 0; i < M.rows; i++) for (int j = 0; j < M.cols; j++) { float pix = (float)M.at<uchar>(i, j); pix = a * (float)pix + b; if ((int)pix > 255) pix = 255; M2.at<uchar>(i, j) = (uchar) pix; } imshow("pic1", M); imshow("pic2", M2); waitKey(0);
3、獲取圖像ROI區域
圖像的ROI(region of interest)是指圖像中感興趣區域、在OpenCV中圖像設置圖像ROI區域,實現對ROI區域操作。
方法1:
img(Rect(100, 100, 100, 100));
Rect代表一個矩形,Rect_ (_Tp _x, _Tp _y, _Tp _width, _Tp _height),參數分別是x,y,width,height。
方法2:
img(Range(100, 200), Range(100,200));
Range表示連續的行或列,Range (int _start, int _end);
示例:
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic1.bmp"); cout << M.rows<<","<<M.cols << endl; Mat roi = M(Rect(30, 50, 150, 170)); imshow("pic1", M); imshow("roi", roi);
4、圖像混合
圖像線性混合,產生類似畫中畫的效果。
h(x)=(1-a)*f(x) + b*g(x)
a的取值范圍為0到1之間,通過對兩幅圖的像素加權得到最終的輸出圖像,兩幅圖像的大小和類型必須完全一致(兩個矩陣相加維度必須一致)。
CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
double beta, double gamma, OutputArray dst, int dtype = -1);
例1:圖片與背景圖混合
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic1.bmp"); cout << M.rows<<","<<M.cols << endl; Mat y(M.rows, M.cols, CV_8UC3, Scalar(0, 50, 100)); Mat dst; addWeighted(M, 0.3, y, 0.7, 0.0, dst); imshow("pic1", M); imshow("y", y); imshow("add", dst);
例2:兩幅圖像混合,先統一尺寸
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic1.bmp"); Mat M2 = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic2.bmp"); M2 = M2(Rect(0, 0, M.cols, M.rows)); //x,y,width,height cout << M.rows<<","<<M.cols << endl; cout << M2.rows << "," << M2.cols << endl; Mat dst; addWeighted(M, 0.7, M2, 0.3, 0.0, dst); imshow("pic1", M); imshow("pic2", M2); imshow("add", dst);
5、圖像多通道分離
1)函數原型
/** @brief Divides a multi-channel array into several single-channel arrays. @param src input multi-channel array. @param mvbegin output array; the number of arrays must match src.channels(); the arrays themselves are reallocated, if needed. */ CV_EXPORTS void split(const Mat& src, Mat* mvbegin); /** @overload @param m input multi-channel array. @param mv output vector of arrays; the arrays themselves are reallocated, if needed. */
2)圖像顏色通道
Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic5.bmp"); vector<Mat> channels; split(M, channels); imshow("pic1", M); imshow("B", channels.at(0)); imshow("G", channels.at(1)); imshow("R", channels.at(2)); /* 方法2 Mat channels[3]; split(M, channels); imshow("pic1", M); imshow("B", channels[0]); imshow("G", channels[1]); imshow("R", channels[2]);
6、圖像多通道合並
圖像合並函數merge是split的逆操作,將多個數組合並成多通道的數組。
merge(const Mat * mv, size_t count, OutputArray dst )
merge(InputArrayOfArrays mv, OutputArray dst )
//圖像合並例子,方式1: Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic5.bmp"); Mat channels[3]; split(M, channels); imshow("pic1", M); imshow("B", channels[0]); imshow("G", channels[1]); imshow("R", channels[2]); Mat dst; merge(channels, 3, dst); imshow("merged", M); //方式2: Mat M = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic5.bmp"); vector<Mat> channels; split(M, channels); imshow("pic1", M); imshow("B", channels.at(0)); imshow("G", channels.at(1)); imshow("R", channels.at(2)); Mat dst; merge(channels, dst); imshow("merged", M);
輸出如下圖。
7、參考文獻
1、《OpenCV3 編程入門》,電子工業出版社,毛星雨著
2、《學習OpenCV》,清華大學出版社,Gary Bradski, Adrian kaehler著
3、opencv常用api簡單分析: split()、merge()
尊重原創技術文章,轉載請注明。