OpenCV阅读图像的像素值
我想用opencv很简单的事情,但得到错误。 我只是想读取16位PNG图像和访问特定的像素值。我尝试了很多方法,但无法管理获得价值。我在windows8 64bit上使用OpenCV3.0。OpenCV阅读图像的像素值
注意:虽然使用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;
}
错误消息:Microsoft C++异常:
在0x00007FF8EB288A5C在OpenCVTest.exe未处理的异常CV ::异常在存储器位置0x000000A47F40F230。
但我认为这是误导性的错误,我检查了我的图像是320 * 240,所以我确定在那个位置有像素。
我试过标量还,但我得到同样的错误
一对夫妇的事情,你应该注意。 首先你要定义frame
两次。
秒,这条线float zmx = frame.at<unsigned char>(118, 38);
有几个问题。您将unsigned char
分配给float
。还应该注意的顺序颠倒来访问你打电话frame.at<unsigned char>(y, x)
的x,y
像素值,那么最好的方式分配给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;
}
你最大的问题是,你试图访问一个16 BPP图像,即与错误的数据类型类型CV_16U
的Mat
。如果是单通道16 bpp图像(我想这里是这种情况),或者对于3通道图像,应该使用frame.at<ushort>(...)
。
此外,您应该确保您正确加载图像。使用imread
与参数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'? – Thesane
请发布错误消息。在这个世界上有无数的错误 – Piglet
@Thsane它只是错误,而我coppying我的代码。,错误是相同的 – seleucia