0

I'm trying to simple load an image (TIFF) and display a pixel value.

If I open the image using ImageJ the values are 32-bit float. But opening the same image using opencv I get really strange float values, e.g. 4.2039e-44.

If I read the value of a specific pixel using "int" the presented value is correct. Below is the code I use to test.

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>

int main(int argc, char **argv) {
    std::string imageFile = "image.tiff";

    cv::Mat image;
    image = cv::imread(imageFile, CV_LOAD_IMAGE_ANYDEPTH);   // Read the file

    if (!image.data)                              // Check for invalid input
    {
        std::cout << "Could not open or find the image: " << imageFile << std::endl;
        return -1;
    }
    std::cout << "Image:" << image.rows << " x " << image.cols << " Channels: " << image.channels() << " Depth: " << image.depth() << std::endl;
    std::cout << "Value at 0,0: " << image.at<float>(0,1)<< std::endl; // Strange Value
    std::cout << "Value at 0,0: " << image.at<int>(0,1)<< std::endl; // Correct Value

    return (EXIT_SUCCESS);
}

Trying to move forward with the code, I decided to create a function to convert the data to "int" reading from the file. As a temporary solution this worked, but I'm still looking for the reason why the data is being loaded wrong.

int main(int argc, char **argv) {
    std::string imageFile = "/home/slepicka/XSConfig/image.tiff";

    cv::Mat image = openImage(imageFile);

    if (!image.data)                              // Check for invalid input
    {
        std::cout << "Could not open or find the image: " << imageFile << std::endl;
        return -1;
    }

    std::cout << "Image:" << image.rows << " x " << image.cols << " Channels: " << image.channels() << " Depth: " << image.depth() << " Type: " << image.type() << std::endl;
    std::cout << "Value at 0,0: " << image.at<int>(0,1)<< std::endl; // Correct Value
    //std::cout << "Data: " << image << std::endl;
    return (EXIT_SUCCESS);
}

cv::Mat openImage(std::string filename){
    cv::Mat imageLoad = cv::imread(filename, CV_LOAD_IMAGE_ANYDEPTH);

    if(imageLoad.type() == CV_32F){
        return convertToInt(imageLoad);
    }

    return imageLoad;

}

cv::Mat convertToInt(cv::Mat source){
    int r, c;
    cv::Mat converted;

    converted.create(source.rows, source.cols, CV_32SC1);

    for (r=0; r<source.rows;r++) {
        for (c=0; c<source.cols;c++) {
            converted.at<int>(r, c) = source.at<int>(r, c);
        }
    }
    return converted;
}
12
  • Maybe this might help?: stackoverflow.com/questions/23433860/opencv-imread-to-mat-float Commented Jun 4, 2015 at 6:25
  • please check image.depth() and image.type(). for sure, your image is not float by default (if you want that, you'll have to convert it explicitly) Commented Jun 4, 2015 at 7:27
  • @berak , the depth is 5 and the image type is also 5. The strange part is that if I open the Image with ImageJ it says that it's a float Image and all the informations from opencv tells me the same, right? Commented Jun 4, 2015 at 14:43
  • 1
    If you prefer to use the work around you already have, may i suggest to do conversion more efficiently. I don't have opencv installed right now so i can't check it but i'm sure you can d something like this: Mat converted(source.size(), CV_32SC1, source.data); Commented Jun 4, 2015 at 20:49
  • 1
    You might have to put "true" as the last parameter to make sure it actually copies the data: Mat converted(source.size(), CV_32SC1, source.data, true); Commented Jun 4, 2015 at 21:03

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.