首页 文章

如何使用OpenCV显示PGM图像

提问于
浏览
3

我正在尝试使用OpenCV(2.4.0)为C加载和显示.PGM图像 .

void open(char* location, int flag, int windowFlag)
{
    Mat image = imread(location, flag);
    namedWindow("Image window", windowFlag);
    imshow("Image window", image);
    waitKey(0);
}

我打电话给这样开:

open("./img_00245_c1.pgm", IMREAD_UNCHANGED, CV_WINDOW_AUTOSIZE);

问题是打开窗口时显示的图像比我用IrfanView打开文件时更暗 . 此外,如果我试图将此图像写入另一个文件,如下所示:

Mat imgWrite;
imgWrite = image;
imwrite("newImage.pgm", imgWrite)

我将获得与原始文件内容不同的文件内容,IrfanView将显示此内容,因为我的功能显示为imshow .

imread for .PGM文件中是否有不同的标志,以便我可以显示和保存原始文件?

EDIT: 图片pgm file

EDIT 2 : 注释:IrfanView将图像标准化为最大像素值255 . 为了使用OpenCV清楚地看到图像,我应该在Mat中加载时对图像进行标准化 . 这是否可以直接使用OpenCV函数而不迭代像素并修改它们的值?

1 回答

  • 1

    问题不在于数据的加载方式,而在于它们的显示方式 .

    您的图像是 CV_16UC1imshowimwrite 将值从原始范围 [0, 65535] 归一化到 [0, 255] 范围,以适合 CV_8U 类型的范围 .

    由于你的PGM图像有 max_value of 4096

    P2        
    1176 640  // width height
    4096      // max_value
    

    它应该从范围 [0, 4096] 而不是 [0, 65535] 进行标准化 . 你可以这样做:

    Mat img = imread("path_to_image", IMREAD_UNCHANGED);
    img.convertTo(img, CV_8U, 255.0 / 4096.0);
    
    imshow("Image", img);
    waitKey();
    

    请注意,图片中的值范围与 [0, 4096] 不对应,但是:

    double minv, maxv;
    minMaxLoc(img, &minv, &maxv);
    
    // minv = 198
    // maxv = 2414
    

    所以_1731368中的直接归一化如下:

    normalize(img, img, 0, 255, NORM_MINMAX);
    img.convertTo(img, CV_8U);
    

    不起作用,因为它会产生比它应该更亮的图像 .


    这意味着要正确显示您的图像,您需要知道 max_value (此处为 4096 ) . 如果每次都更改,您可以检索它解析 .pgm 文件 .

    再次,这只是可视化的问题 . 数据是正确的 .

相关问题