簡體   English   中英

OpenCV讀取圖像像素值

[英]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_ANYDEPTHIMREAD_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM