一、Mat類
Mat類是C++實現的OpenCV庫的核心,表示一個N維度單通或多通道陣列,可以用來存儲實數或復數值向量和數組,灰度或彩色圖像,向量場,張量及直方圖(當然高緯度的直方圖存儲在稀疏Mat類更合適),OpenCV是一個圖像處理庫。它包含大量的圖像處理功能。為了解決計算上的挑戰,大多數時候你最終會使用庫的多個功能。因此,將圖像傳遞給函數是一種常見的做法。我們不應該忘記,我們正在討論圖像處理算法,這些算法往往計算量很大。我們想要做的最后一件事是通過制作不必要的大型圖像副本來進一步降低程序的速度。
為了解決這個問題,OpenCV使用了一個引用計數系統。這個想法是,每個Mat對象都有自己的頭部,但是矩陣可以通過讓它們的矩陣指針指向相同的地址而在它們的兩個實例之間共享。而且,復制操作符只會復制標題和指向大矩陣的指針,而不是數據本身。
1.1創建一個Mat對象
從上可以看出Mat基本上是一個包含兩個數據部分的類:矩陣頭(包含矩陣大小,用於存儲的方法,存儲矩陣的地址等信息)以及包含像素值(取決於選擇用於存儲的方法的任何維度)。矩陣頭部大小是恆定的,但是矩陣本身的大小可能隨着圖像而變化,並且通常比數量級大。
創建一個Mat類型對象可以沒有大小和數據類型,然后通過成員函數create()來分配指定,例如創建一個二維數組,可以使用create(int rows, int cols, types)備注:僅限於二維數組,第三個參數類型既指定了元素的類型又說明了通道數,這些類型都定義在矩陣頭中,格式為:CV_{8U,16S,16U,32S,32F,64F}C{1,2,3},然后通過setTo()函數設定每個通道上的具體數值;
通常定義創建一個Mat類型的對象可以通過構造函數在創建矩陣時即分配內存,其中一個構造函數的參數與create()函數參數相同;
1 //演示示例:創建一個Mat對象數組 2 #include <opencv2/highgui.hpp> 3 #include <opencv2/core.hpp> 4 #include <iostream> 5 6 using namespace std; 7 using namespace cv; 8 9 int main() 10 { 11 Mat array_test; 12 array_test.create( 3, 2, CV_32FC3 ); //create array header 13 array_test.setTo(Scalar(1.0f,2.0f,3.0f)); //set array data 14 15 cout << "array_test = " << endl << array_test << endl; 16 //如下使用構造函數等同上面分布創建 17 Mat array_test_con( 3, 2, CV_32FC3, Scalar(1.0f,2.0f,3.0f) ); 18 cout << "array_test_con = " << endl << array_test_con << endl; 19 return 0; 20 }
1.2 Mat類對象的數據和Mat類矩陣頭
如上敘述,為了解決圖像處理繁雜計算問題,OpenCV使用了一個引用計數系統。這個想法是,針對圖像的數據,每個Mat對象都有自己的頭部相對應,通過讓它們的矩陣指針指向相同的地址而在它們的兩個實例對象之間共享。而且,復制操作符只會復制標題和指向大矩陣的指針,而不是數據本身。
1 //演示示例:矩陣頭Array Header和矩陣數據Array data關系 2 #include <opencv2/highgui.hpp> 3 #include <opencv2/core.hpp> 4 #include <iostream> 5 using namespace std; 6 using namespace cv; 7 8 int main() 9 { 10 Mat A( 2, 2, CV_8UC3, Scalar(10, 20, 30)); 11 12 cout << "A = " << endl << A << endl; 13 14 cout << endl; 15 16 Mat B(A); 17 cout << "B = " << endl << B << endl; 18 19 cout << endl; 20 21 Mat C = A; 22 cout << "C = " << endl << C << endl; 23 24 cout << endl << "After Mat algebra..." << endl; 25 26 Mat A1( 2, 2, CV_8UC3, Scalar(1, 2, 3)); 27 28 A = A +A1; 29 30 cout << "A = " << endl << A << endl; 31 cout << "B = " << endl << B << endl; 32 cout << "C = " << endl << C << endl; 33 34 return 0; 35 }
上述所有對象最后指向相同的單一數據矩陣。然而,它們的標頭是不同的,並且使用它們中的任何一個進行修改也會影響所有其他標簽。實際上,不同的對象只是為相同的底層數據提供不同的訪問方法。不過,它們的矩陣頭部分是真正相互獨立的。這樣,可以創建一個僅包含矩陣數據的一部分的矩陣對象。例如,要在圖像中創建感興趣的區域(ROI),您只需創建一個帶有新邊界的新矩陣頭:
1 #include <opencv2/highgui.hpp> 2 #include <opencv2/core.hpp> 3 #include <iostream> 4 5 using namespace std; 6 using namespace cv; 7 8 int main() 9 { 10 Mat A( 4, 4, CV_8UC3, Scalar(10, 20, 30)); 11 cout << "A = " << endl << A << endl; 12 13 cout << endl; 14 15 Mat B(A); 16 cout << "B = " << endl << B << endl; 17 18 cout << endl; 19 20 Mat C = A; 21 22 cout << "C = " << endl << C << endl; 23 24 cout << endl << "After Mat algebra..." << endl; 25 26 Mat A1( 4, 4, CV_8UC3, Scalar(1, 2, 3)); 27 28 A = A +A1; 29 30 cout << "A = " << endl << A << endl; 31 cout << "B = " << endl << B << endl; 32 cout << "C = " << endl << C << endl; 33 //在圖像中創建感興趣的區域(ROI) 34 Mat D(A, Rect(0,0,2,2)); 35 cout << "D = " << endl << D << endl; 36 37 D.setTo(Scalar(1, 2, 3)); 38 cout << "A = " << endl << A << endl; 39 40 //創建一個帶有新邊界的新矩陣頭 41 Mat E = A(Range::all(), Range(2,3)); 42 cout << "E = " << endl << E << endl; 43 44 E.setTo(Scalar(7, 8, 9)); 45 cout << "A = " << endl << A << endl; 46 47 return 0; 48 }
當想復制矩陣本身,所以OpenCV提供了cv :: Mat :: clone()和cv :: Mat :: copyTo()函數。
1 #include <opencv2/highgui.hpp> 2 #include <opencv2/core.hpp> 3 #include <iostream> 4 5 using namespace std; 6 using namespace cv; 7 8 int main() 9 { 10 Mat A( 4, 4, CV_8UC3, Scalar(10, 20, 30)); 11 cout << "A = " << endl << A << endl; 12 13 cout << endl; 14 15 Mat B(A); 16 cout << "B = " << endl << B << endl; 17 18 cout << endl; 19 20 Mat C = A; 21 cout << "C = " << endl << C << endl; 22 23 cout << endl << "After Mat algebra..." << endl; 24 25 Mat A1( 4, 4, CV_8UC3, Scalar(1, 2, 3)); 26 27 A = A +A1; 28 29 cout << "A = " << endl << A << endl; 30 cout << "B = " << endl << B << endl; 31 cout << "C = " << endl << C << endl; 32 33 Mat D(A, Rect(0,0,2,2)); //拷貝構造函數中Rect僅適用於二維矩陣 34 cout << "D = " << endl << D << endl; 35 36 D.setTo(Scalar(1, 2, 3)); 37 cout << "A = " << endl << A << endl; 38 39 Mat E = A(Range::all(), Range(2,3)); //拷貝構造函數中Range 僅適用於二維矩陣 40 cout << "E = " << endl << E << endl; 41 E.setTo(Scalar(7, 8, 9)); 42 cout << "A = " << endl << A << endl; 43 44 Mat F = A.clone(); 45 cout << "F = " << endl << F << endl; 46 47 Mat G; 48 A.copyTo(G); 49 cout << "G = " << endl << G << endl; 50 51 A.setTo(Scalar(10, 20, 30)); 52 cout << "A = " << endl << A << endl; 53 cout << "F = " << endl << F << endl; 54 cout << "G = " << endl << G << endl; 55 return 0; 56 }
二、SpareMat類
針對稀疏矩陣,OpenCV定義了獨立的數據結構SpareMat類。稀疏矩陣僅存儲非零元素,避免了資源上的浪費,即將節省很多空間尤其針對元素存在許多零元素的數據, 使用稀疏矩陣的常用案例是直方圖,對於直方圖,大多數數據是零,存儲這些零元素又是沒有必要的。
三、數組常用操作
3.1兩數組元素加權相加運算 AddWeighted()
1 void addWeighted( 2 InputArray src1, //第一個輸入矩陣 3 double alpha, //第一個輸入矩陣的權重 4 InputArray src2, //第二個輸入的矩陣 5 double beta, //第二個輸入矩陣的權重 6 double gamma, //權重相加的偏移量 7 OutputArray dst, //輸出的結果 8 int dtype = -1) //輸出結果的類型
即加權的表達式如下:
Dst = α·src1 + β·src2 + γ
該函數可以用來實現alhpa融合(線性融合),即將公式中的γ設置為0,則alpha融合的公式演變為:
Dst = α·src1 + β·src2 = α·src1 + (1-α)·src2
函數中需要兩個源圖像src1和src2,這兩個源圖像可以是任意類型的像素(灰度,彩色),但只要他們屬於同一類型一致即可,所輸出的圖像也是與源圖像的像素類型一致;
注意:源圖像可以是不同尺寸,但融合的操作區域(即感興趣區域ROI)必須尺寸統一,否則OpenCV會產生錯誤;
1 //alpha融合演示示例 2 #include <opencv2/highgui.hpp> 3 #include <iostream> 4 5 using namespace std; 6 using namespace cv; 7 8 int main() 9 { 10 //讀取圖像imread()顯示圖像imshow()函數待后續 11 Mat src1 = imread("D:\\workspace-qt\\OpenCV\\LinuxLogo.jpg"); 12 if(src1.empty()) {cout << "Can't Load the image..." << endl; return -1;} 13 Mat src2 = imread("D:\\workspace-qt\\OpenCV\\WindowsLogo.jpg"); 14 if(src2.empty()) {cout << "Can't Load the image..." << endl; return -1;} 15 Mat dst; 16 addWeighted(src1,0.5,src2,0.5,0.0,dst,-1); 17 imshow("Alpha",dst); 18 waitKey(0); 19 return 0; 20 }
備注:在加權融合圖像的便宜參數γ方面,函數提供了更大的靈活性,一般而言,使α和β不小於0且相加不大於1,那么γ的設定取決於加權后圖像像素所要調整到的平均值或最大值。
3.2 色彩空間轉換 cvColor()
1 void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 )
輸入圖像數組可以是8位數組,16位無符號類型數組,或者32位浮點類型,而輸出圖像數組與輸入數組保持着相同的尺寸大小和深度,轉換操作由參數code來實現,dstCn表示輸出圖像的通道數,默認設為0意味着輸出數組自動由源圖像src和轉換規則code作用后自動獲取;

1 enum ColorConversionCodes { 2 COLOR_BGR2BGRA = 0, //!< add alpha channel to RGB or BGR image 3 COLOR_RGB2RGBA = COLOR_BGR2BGRA, 4 5 COLOR_BGRA2BGR = 1, //!< remove alpha channel from RGB or BGR image 6 COLOR_RGBA2RGB = COLOR_BGRA2BGR, 7 8 COLOR_BGR2RGBA = 2, //!< convert between RGB and BGR color spaces (with or without alpha channel) 9 COLOR_RGB2BGRA = COLOR_BGR2RGBA, 10 11 COLOR_RGBA2BGR = 3, 12 COLOR_BGRA2RGB = COLOR_RGBA2BGR, 13 14 COLOR_BGR2RGB = 4, 15 COLOR_RGB2BGR = COLOR_BGR2RGB, 16 17 COLOR_BGRA2RGBA = 5, 18 COLOR_RGBA2BGRA = COLOR_BGRA2RGBA, 19 20 COLOR_BGR2GRAY = 6, //!< convert between RGB/BGR and grayscale, @ref color_convert_rgb_gray "color conversions" 21 COLOR_RGB2GRAY = 7, 22 COLOR_GRAY2BGR = 8, 23 COLOR_GRAY2RGB = COLOR_GRAY2BGR, 24 COLOR_GRAY2BGRA = 9, 25 COLOR_GRAY2RGBA = COLOR_GRAY2BGRA, 26 COLOR_BGRA2GRAY = 10, 27 COLOR_RGBA2GRAY = 11, 28 29 COLOR_BGR2BGR565 = 12, //!< convert between RGB/BGR and BGR565 (16-bit images) 30 COLOR_RGB2BGR565 = 13, 31 COLOR_BGR5652BGR = 14, 32 COLOR_BGR5652RGB = 15, 33 COLOR_BGRA2BGR565 = 16, 34 COLOR_RGBA2BGR565 = 17, 35 COLOR_BGR5652BGRA = 18, 36 COLOR_BGR5652RGBA = 19, 37 38 COLOR_GRAY2BGR565 = 20, //!< convert between grayscale to BGR565 (16-bit images) 39 COLOR_BGR5652GRAY = 21, 40 41 COLOR_BGR2BGR555 = 22, //!< convert between RGB/BGR and BGR555 (16-bit images) 42 COLOR_RGB2BGR555 = 23, 43 COLOR_BGR5552BGR = 24, 44 COLOR_BGR5552RGB = 25, 45 COLOR_BGRA2BGR555 = 26, 46 COLOR_RGBA2BGR555 = 27, 47 COLOR_BGR5552BGRA = 28, 48 COLOR_BGR5552RGBA = 29, 49 50 COLOR_GRAY2BGR555 = 30, //!< convert between grayscale and BGR555 (16-bit images) 51 COLOR_BGR5552GRAY = 31, 52 53 COLOR_BGR2XYZ = 32, //!< convert RGB/BGR to CIE XYZ, @ref color_convert_rgb_xyz "color conversions" 54 COLOR_RGB2XYZ = 33, 55 COLOR_XYZ2BGR = 34, 56 COLOR_XYZ2RGB = 35, 57 58 COLOR_BGR2YCrCb = 36, //!< convert RGB/BGR to luma-chroma (aka YCC), @ref color_convert_rgb_ycrcb "color conversions" 59 COLOR_RGB2YCrCb = 37, 60 COLOR_YCrCb2BGR = 38, 61 COLOR_YCrCb2RGB = 39, 62 63 COLOR_BGR2HSV = 40, //!< convert RGB/BGR to HSV (hue saturation value), @ref color_convert_rgb_hsv "color conversions" 64 COLOR_RGB2HSV = 41, 65 66 COLOR_BGR2Lab = 44, //!< convert RGB/BGR to CIE Lab, @ref color_convert_rgb_lab "color conversions" 67 COLOR_RGB2Lab = 45, 68 69 COLOR_BGR2Luv = 50, //!< convert RGB/BGR to CIE Luv, @ref color_convert_rgb_luv "color conversions" 70 COLOR_RGB2Luv = 51, 71 COLOR_BGR2HLS = 52, //!< convert RGB/BGR to HLS (hue lightness saturation), @ref color_convert_rgb_hls "color conversions" 72 COLOR_RGB2HLS = 53, 73 74 COLOR_HSV2BGR = 54, //!< backward conversions to RGB/BGR 75 COLOR_HSV2RGB = 55, 76 77 COLOR_Lab2BGR = 56, 78 COLOR_Lab2RGB = 57, 79 COLOR_Luv2BGR = 58, 80 COLOR_Luv2RGB = 59, 81 COLOR_HLS2BGR = 60, 82 COLOR_HLS2RGB = 61, 83 84 COLOR_BGR2HSV_FULL = 66, //!< 85 COLOR_RGB2HSV_FULL = 67, 86 COLOR_BGR2HLS_FULL = 68, 87 COLOR_RGB2HLS_FULL = 69, 88 89 COLOR_HSV2BGR_FULL = 70, 90 COLOR_HSV2RGB_FULL = 71, 91 COLOR_HLS2BGR_FULL = 72, 92 COLOR_HLS2RGB_FULL = 73, 93 94 COLOR_LBGR2Lab = 74, 95 COLOR_LRGB2Lab = 75, 96 COLOR_LBGR2Luv = 76, 97 COLOR_LRGB2Luv = 77, 98 99 COLOR_Lab2LBGR = 78, 100 COLOR_Lab2LRGB = 79, 101 COLOR_Luv2LBGR = 80, 102 COLOR_Luv2LRGB = 81, 103 104 COLOR_BGR2YUV = 82, //!< convert between RGB/BGR and YUV 105 COLOR_RGB2YUV = 83, 106 COLOR_YUV2BGR = 84, 107 COLOR_YUV2RGB = 85, 108 109 //! YUV 4:2:0 family to RGB 110 COLOR_YUV2RGB_NV12 = 90, 111 COLOR_YUV2BGR_NV12 = 91, 112 COLOR_YUV2RGB_NV21 = 92, 113 COLOR_YUV2BGR_NV21 = 93, 114 COLOR_YUV420sp2RGB = COLOR_YUV2RGB_NV21, 115 COLOR_YUV420sp2BGR = COLOR_YUV2BGR_NV21, 116 117 COLOR_YUV2RGBA_NV12 = 94, 118 COLOR_YUV2BGRA_NV12 = 95, 119 COLOR_YUV2RGBA_NV21 = 96, 120 COLOR_YUV2BGRA_NV21 = 97, 121 COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21, 122 COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21, 123 124 COLOR_YUV2RGB_YV12 = 98, 125 COLOR_YUV2BGR_YV12 = 99, 126 COLOR_YUV2RGB_IYUV = 100, 127 COLOR_YUV2BGR_IYUV = 101, 128 COLOR_YUV2RGB_I420 = COLOR_YUV2RGB_IYUV, 129 COLOR_YUV2BGR_I420 = COLOR_YUV2BGR_IYUV, 130 COLOR_YUV420p2RGB = COLOR_YUV2RGB_YV12, 131 COLOR_YUV420p2BGR = COLOR_YUV2BGR_YV12, 132 133 COLOR_YUV2RGBA_YV12 = 102, 134 COLOR_YUV2BGRA_YV12 = 103, 135 COLOR_YUV2RGBA_IYUV = 104, 136 COLOR_YUV2BGRA_IYUV = 105, 137 COLOR_YUV2RGBA_I420 = COLOR_YUV2RGBA_IYUV, 138 COLOR_YUV2BGRA_I420 = COLOR_YUV2BGRA_IYUV, 139 COLOR_YUV420p2RGBA = COLOR_YUV2RGBA_YV12, 140 COLOR_YUV420p2BGRA = COLOR_YUV2BGRA_YV12, 141 142 COLOR_YUV2GRAY_420 = 106, 143 COLOR_YUV2GRAY_NV21 = COLOR_YUV2GRAY_420, 144 COLOR_YUV2GRAY_NV12 = COLOR_YUV2GRAY_420, 145 COLOR_YUV2GRAY_YV12 = COLOR_YUV2GRAY_420, 146 COLOR_YUV2GRAY_IYUV = COLOR_YUV2GRAY_420, 147 COLOR_YUV2GRAY_I420 = COLOR_YUV2GRAY_420, 148 COLOR_YUV420sp2GRAY = COLOR_YUV2GRAY_420, 149 COLOR_YUV420p2GRAY = COLOR_YUV2GRAY_420, 150 151 //! YUV 4:2:2 family to RGB 152 COLOR_YUV2RGB_UYVY = 107, 153 COLOR_YUV2BGR_UYVY = 108, 154 //COLOR_YUV2RGB_VYUY = 109, 155 //COLOR_YUV2BGR_VYUY = 110, 156 COLOR_YUV2RGB_Y422 = COLOR_YUV2RGB_UYVY, 157 COLOR_YUV2BGR_Y422 = COLOR_YUV2BGR_UYVY, 158 COLOR_YUV2RGB_UYNV = COLOR_YUV2RGB_UYVY, 159 COLOR_YUV2BGR_UYNV = COLOR_YUV2BGR_UYVY, 160 161 COLOR_YUV2RGBA_UYVY = 111, 162 COLOR_YUV2BGRA_UYVY = 112, 163 //COLOR_YUV2RGBA_VYUY = 113, 164 //COLOR_YUV2BGRA_VYUY = 114, 165 COLOR_YUV2RGBA_Y422 = COLOR_YUV2RGBA_UYVY, 166 COLOR_YUV2BGRA_Y422 = COLOR_YUV2BGRA_UYVY, 167 COLOR_YUV2RGBA_UYNV = COLOR_YUV2RGBA_UYVY, 168 COLOR_YUV2BGRA_UYNV = COLOR_YUV2BGRA_UYVY, 169 170 COLOR_YUV2RGB_YUY2 = 115, 171 COLOR_YUV2BGR_YUY2 = 116, 172 COLOR_YUV2RGB_YVYU = 117, 173 COLOR_YUV2BGR_YVYU = 118, 174 COLOR_YUV2RGB_YUYV = COLOR_YUV2RGB_YUY2, 175 COLOR_YUV2BGR_YUYV = COLOR_YUV2BGR_YUY2, 176 COLOR_YUV2RGB_YUNV = COLOR_YUV2RGB_YUY2, 177 COLOR_YUV2BGR_YUNV = COLOR_YUV2BGR_YUY2, 178 179 COLOR_YUV2RGBA_YUY2 = 119, 180 COLOR_YUV2BGRA_YUY2 = 120, 181 COLOR_YUV2RGBA_YVYU = 121, 182 COLOR_YUV2BGRA_YVYU = 122, 183 COLOR_YUV2RGBA_YUYV = COLOR_YUV2RGBA_YUY2, 184 COLOR_YUV2BGRA_YUYV = COLOR_YUV2BGRA_YUY2, 185 COLOR_YUV2RGBA_YUNV = COLOR_YUV2RGBA_YUY2, 186 COLOR_YUV2BGRA_YUNV = COLOR_YUV2BGRA_YUY2, 187 188 COLOR_YUV2GRAY_UYVY = 123, 189 COLOR_YUV2GRAY_YUY2 = 124, 190 //CV_YUV2GRAY_VYUY = CV_YUV2GRAY_UYVY, 191 COLOR_YUV2GRAY_Y422 = COLOR_YUV2GRAY_UYVY, 192 COLOR_YUV2GRAY_UYNV = COLOR_YUV2GRAY_UYVY, 193 COLOR_YUV2GRAY_YVYU = COLOR_YUV2GRAY_YUY2, 194 COLOR_YUV2GRAY_YUYV = COLOR_YUV2GRAY_YUY2, 195 COLOR_YUV2GRAY_YUNV = COLOR_YUV2GRAY_YUY2, 196 197 //! alpha premultiplication 198 COLOR_RGBA2mRGBA = 125, 199 COLOR_mRGBA2RGBA = 126, 200 201 //! RGB to YUV 4:2:0 family 202 COLOR_RGB2YUV_I420 = 127, 203 COLOR_BGR2YUV_I420 = 128, 204 COLOR_RGB2YUV_IYUV = COLOR_RGB2YUV_I420, 205 COLOR_BGR2YUV_IYUV = COLOR_BGR2YUV_I420, 206 207 COLOR_RGBA2YUV_I420 = 129, 208 COLOR_BGRA2YUV_I420 = 130, 209 COLOR_RGBA2YUV_IYUV = COLOR_RGBA2YUV_I420, 210 COLOR_BGRA2YUV_IYUV = COLOR_BGRA2YUV_I420, 211 COLOR_RGB2YUV_YV12 = 131, 212 COLOR_BGR2YUV_YV12 = 132, 213 COLOR_RGBA2YUV_YV12 = 133, 214 COLOR_BGRA2YUV_YV12 = 134, 215 216 //! Demosaicing 217 COLOR_BayerBG2BGR = 46, 218 COLOR_BayerGB2BGR = 47, 219 COLOR_BayerRG2BGR = 48, 220 COLOR_BayerGR2BGR = 49, 221 222 COLOR_BayerBG2RGB = COLOR_BayerRG2BGR, 223 COLOR_BayerGB2RGB = COLOR_BayerGR2BGR, 224 COLOR_BayerRG2RGB = COLOR_BayerBG2BGR, 225 COLOR_BayerGR2RGB = COLOR_BayerGB2BGR, 226 227 COLOR_BayerBG2GRAY = 86, 228 COLOR_BayerGB2GRAY = 87, 229 COLOR_BayerRG2GRAY = 88, 230 COLOR_BayerGR2GRAY = 89, 231 232 //! Demosaicing using Variable Number of Gradients 233 COLOR_BayerBG2BGR_VNG = 62, 234 COLOR_BayerGB2BGR_VNG = 63, 235 COLOR_BayerRG2BGR_VNG = 64, 236 COLOR_BayerGR2BGR_VNG = 65, 237 238 COLOR_BayerBG2RGB_VNG = COLOR_BayerRG2BGR_VNG, 239 COLOR_BayerGB2RGB_VNG = COLOR_BayerGR2BGR_VNG, 240 COLOR_BayerRG2RGB_VNG = COLOR_BayerBG2BGR_VNG, 241 COLOR_BayerGR2RGB_VNG = COLOR_BayerGB2BGR_VNG, 242 243 //! Edge-Aware Demosaicing 244 COLOR_BayerBG2BGR_EA = 135, 245 COLOR_BayerGB2BGR_EA = 136, 246 COLOR_BayerRG2BGR_EA = 137, 247 COLOR_BayerGR2BGR_EA = 138, 248 249 COLOR_BayerBG2RGB_EA = COLOR_BayerRG2BGR_EA, 250 COLOR_BayerGB2RGB_EA = COLOR_BayerGR2BGR_EA, 251 COLOR_BayerRG2RGB_EA = COLOR_BayerBG2BGR_EA, 252 COLOR_BayerGR2RGB_EA = COLOR_BayerGB2BGR_EA, 253 254 //! Demosaicing with alpha channel 255 COLOR_BayerBG2BGRA = 139, 256 COLOR_BayerGB2BGRA = 140, 257 COLOR_BayerRG2BGRA = 141, 258 COLOR_BayerGR2BGRA = 142, 259 260 COLOR_BayerBG2RGBA = COLOR_BayerRG2BGRA, 261 COLOR_BayerGB2RGBA = COLOR_BayerGR2BGRA, 262 COLOR_BayerRG2RGBA = COLOR_BayerBG2BGRA, 263 COLOR_BayerGR2RGBA = COLOR_BayerGB2BGRA, 264 265 COLOR_COLORCVT_MAX = 143 266 };
備注:色彩空間轉換都用到如下約定:
1 8位圖像的范圍:0~255 2 16位圖像的范圍:0~65536 3 浮點數的范圍:0.0~1.0 4 黑白圖像轉換位彩色圖像時,最終圖形與黑白圖像的通道數相同 5 彩色圖像轉換為灰度圖像時,灰度值計算使用加權公式: 6 Y= 0.299R+0.587G+0.114B
針對HSV色彩模式或者HLS色彩模式來說色調范圍通常Rang(0,360);
當HSV色彩模式以8位圖像形式輸出時,色調應處以2,才能不出現問題;
1 //RGB轉Gray演示示例 2 #include <opencv2/highgui.hpp> 3 #include <opencv2/imgproc.hpp> 4 #include <iostream> 5 6 using namespace std; 7 using namespace cv; 8 9 int main() 10 { 11 Mat src2 = imread("D:\\workspace-qt\\OpenCV\\WindowsLogo.jpg"); 12 if(src2.empty()) {cout << "Can't Load the image..." << endl; return -1;} 13 14 Mat dst_gray; 15 cvtColor(src2,dst_gray,CV_BGR2GRAY); 16 imshow("Alpha",dst_gray); 17 waitKey(0); 18 return 0; 19 }
3.3 圖像翻轉flip()
void flip(InputArray src, OutputArray dst, int flipCode)
將圖像繞X軸或者Y周或繞X軸Y軸上同時旋轉,取決於參數flipCode的設置
1 圖像繞X軸旋轉:flipCode = 0; 2 圖像繞Y軸旋轉:flipCode = 1; 3 圖像繞X軸和Y軸同時旋轉:flipCode = -1;
常用於圖像坐標原點在左上角和左下角的變換時使用,尤其是進行視頻處理所進行的圖像格式變化;
1 #include <opencv2/highgui.hpp> 2 #include <opencv2/imgproc.hpp> 3 #include <iostream> 4 5 using namespace std; 6 using namespace cv; 7 8 int main() 9 { 10 Mat src = imread("D:\\workspace-qt\\OpenCV\\WindowsLogo.jpg"); 11 if(src.empty()) {cout << "Can't Load the image..." << endl; return -1;} 12 13 imshow("src",src); 14 Mat dst_x, dst_y, dst_x_y; 15 flip(src,dst_x,0); 16 flip(src,dst_y,1); 17 flip(src,dst_x_y,-1); 18 imshow("flipCode = 0",dst_x); 19 imshow("flipCode = 1",dst_y); 20 imshow("flipCode = -1",dst_x_y); 21 waitKey(0); 22 return 0; 23 }