本次實驗通過一個簡短的例子,主要來說明下面4個問題:
1.?坐標體系中的零點坐標為圖片的左上角,X軸為圖像矩形的上面那條水平線;Y軸為圖像矩形左邊的那條垂直線。該坐標體系在諸如結構體Mat,Rect,Point中都是適用的。(OpenCV中有些數據結構的坐標原點是在圖片的左下角,可以設置的)。
2. 在使用image.at<TP>(x1, x2)來訪問圖像中點的值的時候,x1并不是圖片中對應點的x軸坐標,而是圖片中對應點的y坐標。因此其訪問的結果其實是訪問image圖像中的Point(x2, x1)點,即與image.at<TP>(Point(x2, x1))效果相同。
3. 如果所畫圖像是多通道的,比如說image圖像的通道數時n,則使用Mat::at(x, y)時,其x的范圍依舊是0到image的height,而y的取值范圍則是0到image的width乘以n,因為這個時候是有n個通道,所以每個像素需要占有n列。但是如果在同樣的情況下,使用Mat::at(point)來訪問的話,則這時候可以不用考慮通道的個數,因為你要賦值給獲取Mat::at(point)的值時,都不是一個數字,而是一個對應的n維向量。
4. 多通道圖像在使用minMaxLoc()函數是不能給出其最大最小值坐標的,因為每個像素點其實有多個坐標,所以是不會給出的。因此在編程時,這2個位置應該給NULL。
實驗代碼及注釋
main.cpp:?
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>using namespace std;
using namespace cv;int main()
{Mat image, image_3c;image.create(Size(256, 256), CV_8UC1);image_3c.create(Size(256, 256), CV_8UC3); //3通道的圖像image.setTo(0);image_3c.setTo(0);image.at<uchar>(10, 200) = 255; //使用at函數的地方,用的是10,200Point point(20, 100);image.at<uchar>(point) = 250;//使用at函數的地方,用的是Point(10,200)image_3c.at<uchar>(10, 300) = 255;image_3c.at<uchar>(10, 302) = 254;Point point_3c(20, 200);image_3c.at<uchar>(point_3c) = 250;double maxVal = 0; //最大值一定要賦初值,否則運行時會報錯Point maxLoc;minMaxLoc(image, NULL, &maxVal, NULL, &maxLoc);cout << "單通道圖像最大值: " << maxVal << endl;double min_3c, max_3c;//注意多通道在使用minMaxLoc()函數是不能給出其最大最小值坐標的,因為每個像素點其實有多個坐標,所以是不會給出的minMaxLoc(image_3c, &min_3c, &max_3c, NULL, NULL);cout << "3通道圖像最大值: " << max_3c << endl;imshow("image", image);imshow("image_3c", image_3c);waitKey(0);return 0;
}
實驗結果:
單通道圖像的輸出結果如下所示:
由上圖可以看出,黑色的圖像中有2個白色的點(讀者可以仔細看下,由于只有1個像素點,所以需要自己找下,呵呵)的位置是不同的,因此可以證明Mat::at(x,y)和Mat::at(Point(x, y))是有區別的。
?
3通道圖像的輸出結果如下所示:
由上圖可以看出,3通道的圖像也是有2個點的,但是程序中在使用Mat::at(x, y)其y的值為300和302,這已經超出了圖像的寬度256。這同時證明了實驗基礎中的第3點。
?
后臺輸出結果如下:
?
實驗總結:由此可見,平時一定要注意一些細節上的東西。
- 頂
- 0