C++ OpenCV读取图像像素值

C++ OpenCV读取图像像素值,c++,opencv,image-processing,visual-studio-2013,C++,Opencv,Image Processing,Visual Studio 2013,我试图用opencv做一件非常简单的事情,但却出现了错误。 我只是尝试读取16位png图像并访问特定的像素值。我尝试了很多方法,但都无法获得价值。我在windows8 64位上使用OpenCV3.0 注意:当使用CV\U LOAD\U image\U灰度读取图像时,效果良好,但CV\U LOAD\U image\U存在任何深度上升错误。但当我使用CV\u LOAD\u IMAGE\u灰度时,我的最高像素是9,应该在2000左右 我上传了示例图像 我的示例代码: #include "opencv2

我试图用opencv做一件非常简单的事情,但却出现了错误。 我只是尝试读取16位png图像并访问特定的像素值。我尝试了很多方法,但都无法获得价值。我在windows8 64位上使用OpenCV3.0

注意:当使用CV\U LOAD\U image\U灰度读取图像时,效果良好,但CV\U LOAD\U image\U存在任何深度上升错误。但当我使用CV\u LOAD\u IMAGE\u灰度时,我的最高像素是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;
#包括“opencv2/core/core.hpp”
#包括“opencv2/imgproc/imgproc.hpp”
#包括“opencv2/highgui/highgui.hpp”
int _tmain(int argc,_TCHAR*argv[]
{
cv::Mat frame=cv::imread(“文件路径”,cv_LOAD_IMAGE_ANYDEPTH);//使用cv_LOAD_IMAGE_灰度可以,但cv_LOAD_IMAGE_ANYDEPTH上升错误
frame.convertTo(frame,CV_16U);//当然……我也省略了这一部分,并且出现了相同的错误
双最小值,最大值;
cv::点mloc,mxloc;
cv::minMaxLoc(帧、最小值、最大值、最大值、最小值和最大值);
//我可以访问最小值和最大值,但不能访问特定像素值
float zmx=frame.at(118,38);//上升误差
float zm=frame.at(30,40);//上升误差
返回0;
}

错误消息:

OpenCVTest.exe 0x09007FF8EB28 8A5C未处理异常:微软C++异常:CV::内存位置0x000 00 A47 F40F230.< /P> 但我认为这是一个误导性的错误,我检查了我的图像是320*240,所以我确定那个位置有像素


我也尝试了Scalar,但我得到了相同的错误,有几件事你应该注意。
首先定义两次
frame

第二,这一行
float zmx=frame.at(118,38)有几个问题。您正在将
无符号字符
分配给
浮点
。您还应该注意到,访问调用帧的
x,y
像素值的顺序是相反的。在(y,x)
处,最好是这样分配给
标量

Scalar fmx = frame.at<uchar>(118, 38);
最后一件事,确保您正确加载了图像,并且
frame
包含图像数据


更新

我刚刚测试了你的代码,它工作得很好(检查下面),除了在提供的路径中找不到图像之外,我想不出任何东西

#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;
}

您最大的问题是,您试图访问一个16 bpp的映像,即类型为
CV_16U
Mat
,数据类型错误。对于单通道16 bpp图像(我想这里就是这种情况),您应该使用
frame.at(…)
,对于3通道图像,您应该使用
frame.at(…)

此外,还应确保正确加载图像。使用
imread
和参数
imread\u GRAYSCALE
将图像转换为8bpp,这不是您想要的。您应该使用
IMREAD\u ANYDEPTH
IMREAD\u 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;
}
#包括
int main()
{
//将图像作为原始bpp读取
cv::Mat frame=cv::imread(“路径到图像”,cv::imread\u ANYDEPTH);
//确保图像已加载
if(frame.empty())
{
//没有加载图像
返回-1;
}
//确保图像为16bpp和单通道
if(frame.type()!=CV|16U | frame.channels()!=1)
{
//图像深度或通道错误
返回-1;
}
双最小值,最大值;
cv::点最小位置、最大位置;
cv::minMaxLoc(帧、最小值、最大值、最小值和最大值);
//使用正确的数据类型访问值
ushort zmx=帧位置(最大位置);
返回0;
}

您正在定义
两次?请发布错误消息。这里面有无数的错误world@Thsane这只是我在复制代码时的一个错误。错误是相同的。16位通常是“short”类型。可能是您的未签名。正如我在下面的行中所评论的,错误也在上升,我尝试了标量,错误也是相同的,即使没有任何赋值,我也会得到相同的错误。您确定图像已加载到帧中吗??加载后检查帧大小
int rows=frame.rows;int cols=frame.cols。可能是错误的路径是的,我打印了行和列,我可以在调试时看到这些值。如果要读取浮点值,为什么要将图像转换为cv16u?是否可以尝试使用CV_LOAD_image_ANYDEPTH,因为这是一个错误。我现在明白了
#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;
}
#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;
}