[英]OpenCV reading image pixel value
我正在嘗試使用opencv做非常簡單的事情,但出現錯誤。 我只是嘗試讀取16位png圖像並訪問特定的像素值。 我嘗試了很多方法,但無法管理獲取價值。 我在Windows8 64位上使用OpenCV3.0。
注意:使用CV_LOAD_IMAGE_GRAYSCALE讀取圖像時可以,但是CV_LOAD_IMAGE_ANYDEPTH上升錯誤。 但是當我使用CV_LOAD_IMAGE_GRAYSCALE時,我的最高像素是9,應該在2000左右
我上傳了示例圖片。 示例圖片
我的示例代碼:
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
cv::Mat frame = cv::imread("filepath", CV_LOAD_IMAGE_ANYDEPTH );//using CV_LOAD_IMAGE_GRAYSCALE is fine, but CV_LOAD_IMAGE_ANYDEPTH rising error
frame.convertTo(frame, CV_16U);// to be sure... i omitted this part also and same error
double min, max;
cv::Point mloc, mxloc;
cv::minMaxLoc(frame, &min, &max, &mloc, &mxloc);
//i can access min and max values but not the specific pixel value
float zmx = frame.at<unsigned char>(118, 38);//rise error
float zm = frame.at<float>(30,40);//rise error
return 0;
}
錯誤信息:
OpenCVTest.exe中0x00007FF8EB288A5C的未處理異常:Microsoft C ++異常:內存位置0x000000A47F40F230的cv :: Exception。
但是我認為這是一個誤導性錯誤,我檢查我的圖像是否為320 * 240,因此我確定該位置有像素。
我也嘗試過Scalar,但出現了同樣的錯誤
您最大的問題是您正在嘗試訪問16 bpp圖像,即數據類型錯誤的CV_16U
類型的Mat
。 如果是單通道16 bpp圖像(我想是這種情況),則應使用frame.at<ushort>(...)
,對於3通道圖像,應使用frame.at<Vec3w>(...)
。
另外,您還應確保正確加載圖像。 通過將imread
與參數IMREAD_GRAYSCALE
使用,您IMREAD_GRAYSCALE
圖像轉換為8bpp,這不是您想要的。 您應該使用IMREAD_ANYDEPTH
或IMREAD_UNCHANGED
。
看一下這段代碼:
#include<opencv2/opencv.hpp>
int main()
{
// Read the image as original bpp
cv::Mat frame = cv::imread("path_to_image", cv::IMREAD_ANYDEPTH);
// Be sure that the image is loaded
if (frame.empty())
{
// No image loaded
return -1;
}
// Be sure that the image is 16bpp and single channel
if (frame.type() != CV_16U || frame.channels() != 1)
{
// Wrong image depth or channels
return -1;
}
double min_val, max_val;
cv::Point min_loc, max_loc;
cv::minMaxLoc(frame, &min_val, &max_val, &min_loc, &max_loc);
// Access values with correct data type
ushort zmx = frame.at<ushort>(max_loc);
return 0;
}
您應該注意幾件事。 首先,您要定義兩次frame
。
第二行float zmx = frame.at<unsigned char>(118, 38);
有幾個問題。 您正在將unsigned char
分配給float
。 您還應該注意順序相反,以訪問您調用frame.at<unsigned char>(y, x)
的x,y
像素值frame.at<unsigned char>(y, x)
然后最好的方法是分配給Scalar
Scalar fmx = frame.at<uchar>(118, 38);
或使用Point
避免混淆
Scalar fmx = frame.at<uchar>(Point(38,118));
最后一件事,請確保您已正確加載圖像,並且該frame
具有圖像數據
UPDATE
我剛剛測試了您的代碼,它運行良好(請檢查下面的內容),我什么都沒想到,但在提供的路徑中找不到圖像
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
int main(int argc, char** argv)
{
cv::Mat frame = cv::imread("0FD0X.png", CV_LOAD_IMAGE_GRAYSCALE);
frame.convertTo(frame, CV_16U);// to be sure... i omitted this part also and same error
double min, max;
cv::Point mloc, mxloc;
cv::minMaxLoc(frame, &min, &max, &mloc, &mxloc);
//i can access min and max values but not the specific pixel value
float zmx = frame.at<unsigned char>(118, 38);// no error
float zm = frame.at<float>(30, 40);// no error
std::cout << zmx << std::endl; // out 0
std::cout << min << std::endl; // out 0
std::cout << max << std::endl; // out 9
std::cout << mloc << std::endl; // out [0,0]
std::cout << mxloc << std::endl; // out [125,30]
return 0;
}
更新#2以訪問您需要使用Vec3b
數據類型訪問的多通道圖像。 還要注意點坐標的順序。 檢查以下代碼
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
int main(int argc, char** argv)
{
cv::Mat frame = cv::imread("0FD0X.png", CV_LOAD_IMAGE_ANYDEPTH);
frame.convertTo(frame, CV_16U);// to be sure... i omitted this part also and same error
double min, max;
cv::Point mloc, mxloc;
cv::minMaxLoc(frame, &min, &max, &mloc, &mxloc);
//i can access min and max values but not the specific pixel value
ushort pValShort = frame.at<ushort>(38, 118);// no error
Vec3b pValVec = frame.at<Vec3b>(38, 118);// no error
Vec3b pValVecPoint = frame.at<Vec3b>(Point(118,38));// no error
std::cout << pValShort << std::endl; // out 2423
std::cout << pValVec << std::endl; // out [166,8,165]
std::cout << pValVecPoint << std::endl; // out [166,8,165]
std::cout << min << std::endl; // out 0
std::cout << max << std::endl; // out 2423
std::cout << mloc << std::endl; // out [0,0]
std::cout << mxloc << std::endl; // out [118,38]
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.