C++之OpenCV入門到提高005:005 影像操作

可均可可發表於2024-11-15
一、介紹
    今天是這個系列《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 的第五篇文章,其實也沒那麼難,感覺是不是還是很好入門的,那就繼續。初見成效,繼續努力。皇天不負有心人,不忘初心,繼續努力,做自己喜歡做的,開心就好。

相關文章