今天是這個系列《C++之 Opencv 入門到提高》得第五篇文章。這篇文章也不難,介紹如何影像的基本操作,比如:讀取一張圖片的畫素值,如何修改一張圖片中的畫素值,如何讀取一張圖片,如何儲存一張圖片等等,這都是基礎,為以後的學習做好鋪墊。雖然操作很簡單,但是背後有很多東西需要我們深究,才能做到知其然知其所以然。OpenCV 具體的簡介內容,我就不多說了,網上很多,大家可以自行腦補。
OpenCV 的官網地址:https://opencv.org/,元件下載地址:https://opencv.org/releases/。
OpenCV 官網學習網站:https://docs.opencv.ac.cn/4.10.0/index.html
我需要進行說明,以防大家不清楚,具體情況我已經羅列出來。
作業系統:Windows Professional 10(64位)
開發元件:OpenCV – 4.10.0
開發工具:Microsoft Visual Studio Community 2022 (64 位) - Current版本 17.8.3
開發語言:C++(VC16)
二、知識學習
這些都是影像的基本操作,所以並不會很難,但是這也是學好 openCV的基礎。內容很簡單,就不說過多的廢話了,所有講解都在程式碼的註釋中。
1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 #include <math.h> 4 5 using namespace std; 6 using namespace cv; 7 8 /// <summary> 9 /// 影像的操作 10 /// 1、讀寫影像 11 /// 2、讀寫畫素 12 /// 3、修改畫素值 13 /// </summary> 14 /// <returns></returns> 15 int main() 16 { 17 //1、讀寫影像 18 //1.1、imread 可以指定載入灰度或者 RGB 影像 19 //1.2、imwrite 可以儲存影像,型別由副檔名決定。 20 Mat src; 21 src = imread("D:\\360MoveData\\Users\\Administrator\\Desktop\\TestImage\\demo-gril.png", IMREAD_UNCHANGED); 22 if (src.empty()) 23 { 24 cout << "影像載入失敗!!!" << endl; 25 return -1; 26 } 27 28 namedWindow("原圖", WINDOW_AUTOSIZE); 29 imshow("原圖", src); 30 31 //2、讀寫畫素 32 //2.1、都一個灰度(Gray)畫素的畫素值(CV_8UC1) 33 // Scalar intensity=src.at<uchar>(row,col); 34 // Scalar intensity=src.at<uchar>(Point(row,col)); 35 // 36 //2.2、讀一個彩色(RGB)畫素點的畫素值。 37 // Vec3f intensity=src.at<Vec3f>(row,col); 38 // float blue=intensity.val[0]; 39 // float green=intensity.val[1]; 40 // float red=intensity.val[2]; 41 // 42 // Vec3f 就是 float 型別的 RGB 資料 43 // 44 //2.3、修改單通道灰度畫素值 45 // src.at<uchar>(row,col)=128; 46 // 47 // 2.4、修改RGB 三通道畫素值 48 // src.at<Vec3b>(row,col)[0]=128; 49 // src.at<Vec3b>(row,col)[1]=128; 50 // src.at<Vec3b>(row,col)[2]=128; 51 // 52 // 2.5、空白畫素賦值 53 // src=Scalar(0); 54 // 55 // 56 // 2.6、Vec3b 與 Vec3f 57 // 2.6.1、Vec3b 對應三通道的順序是 blue,green,red 的 uchar 型別資料 58 // 2.6.2、Vec3f 對應三通道的順序是 blue,green,red 的 float 型別資料 59 // 2.6.3、把 CV_8UC1 轉換為 CV32F1 實現如下:src.convertTo(dst,CV_32F); 60 // 61 //2.1、讀取單通道畫素值,示例程式碼: 62 Mat graySrc; 63 cvtColor(src, graySrc, COLOR_BGR2GRAY);//將彩色的 RGB 3 通道的轉換為灰度單通道的圖片。 64 namedWindow("單通道灰度影像", WINDOW_AUTOSIZE); 65 imshow("單通道灰度影像", graySrc); 66 67 int width = graySrc.cols; 68 int height = graySrc.rows; 69 70 for (int row = 0; row < height; row++) 71 { 72 for (int col = 0; col < width; col++) 73 { 74 //讀取單通道、灰度的畫素值 75 int gray = graySrc.at<uchar>(row, col); 76 //修改單通道、灰度的畫素值 77 graySrc.at<uchar>(row, col) = 255 - gray; 78 } 79 } 80 81 imshow("修改後單通道灰度影像", graySrc);//可以直接使用顯示影像,他會自動建立顯示圖片的視窗。 82 83 //處理多通道、彩色的影像 84 width = src.cols; 85 height = src.rows; 86 int channes = src.channels(); 87 88 Mat dst; 89 dst.create(src.size(),src.type()); 90 91 for (int row = 0; row < height; row++) 92 { 93 for (int col = 0; col < width; col++) 94 { 95 if (channes == 1) 96 { 97 //讀取單通道、灰度的畫素值 98 int gray = src.at<uchar>(row, col); 99 //修改單通道、灰度的畫素值 100 src.at<uchar>(row, col) = 255 - gray; 101 } 102 else 103 { 104 //讀取多通道、彩色畫素值。Vec3b 就是指具有3個通道的 BGR 的資料結構 105 Vec3b myvalue=src.at<Vec3b>(row, col); 106 int b = myvalue.val[0]; 107 int g = myvalue.val[1]; 108 int r = myvalue.val[2]; 109 110 //修改多通道、彩色畫素值,這是取反效果。 111 /*dst.at<Vec3b>(row, col)[0] = 255 - b; 112 dst.at<Vec3b>(row, col)[1] = 255 - g; 113 dst.at<Vec3b>(row, col)[2] = 255 - r;*/ 114 115 //修改多通道、彩色畫素值,這是隻包含藍色和綠色,青就是色。 116 /*dst.at<Vec3b>(row, col)[0] = b; 117 dst.at<Vec3b>(row, col)[1] = g; 118 dst.at<Vec3b>(row, col)[2] = 0;*/ 119 120 //修改多通道、彩色畫素值,這是隻包含藍色和紅色,就是紫色。 121 /*dst.at<Vec3b>(row, col)[0] = b; 122 dst.at<Vec3b>(row, col)[1] = 0; 123 dst.at<Vec3b>(row, col)[2] = r;*/ 124 125 //修改多通道、彩色畫素值,這是隻包含綠色和紅色,就是黃色。 126 dst.at<Vec3b>(row, col)[0] = 0; 127 dst.at<Vec3b>(row, col)[1] = g; 128 dst.at<Vec3b>(row, col)[2] = r; 129 130 //graySrc.at<uchar>(row, col) = min(r,min(b,g));取灰色第二個方法 131 } 132 } 133 } 134 135 imshow("修改後單、多通道影像", dst);//可以直接使用顯示影像,他會自動建立顯示圖片的視窗。 136 //imshow("單通道灰度影像", graySrc); 137 //opencv 介面也可以實現這樣反差的效果 138 bitwise_not(src, dst); 139 140 imshow("bitwise_not 修改後單、多通道影像", dst);//可以直接使用顯示影像,他會自動建立顯示圖片的視窗。 141 142 143 waitKey(0); 144 145 system("pause"); 146 return 0; 147 }
程式碼很簡單,就不多說了。
效果如圖:
以上就是影像修改後的效果圖。
三、總結
這是 C++ 使用 OpenCV 的第五篇文章,其實也沒那麼難,感覺是不是還是很好入門的,那就繼續。初見成效,繼續努力。皇天不負有心人,不忘初心,繼續努力,做自己喜歡做的,開心就好。