簡體   English   中英

在 opencv 中使用 imwrite 保存圖像寫入全黑但 imshow 顯示正確

[英]Saving an image with imwrite in opencv writes all black but imshow shows correctly

原始問題

此示例代碼將顯示正確創建的圖像,但將保存只有黑色像素的 png。 Mat 采用 CV_32FC3 格式,因此有 3 個浮動通道。

我發現的已回答問題涉及圖像處理問題或錯誤轉換或使用各種壓縮保存為 jpeg。

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

using namespace std;
using namespace cv;

int main()
{
    int i = 0;
    int j = 0;

    Vec3f intensity;
     cv::Mat imageF;
    imageF= cv::Mat::zeros(36,36,CV_32FC3);

    for(j=0;j<imageF.cols;++j){
    for(i=0;i<imageF.rows;++i){
        intensity = imageF.at<Vec3f>(j, i);
        intensity.val[2] = 0.789347;
        intensity.val[1] = 0.772673;
        intensity.val[0] = 0.692689;
        imageF.at<Vec3f>(j, i) = intensity;
    }}
    imshow("Output", imageF);  
    imwrite("test.png", imageF);

    waitKey(0);
    return 0;
}

需要進行哪些更改才能使其按預期保存?

貝瑞爾的解決方案

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

using namespace std;
using namespace cv;

int main() {
    int i = 0;
    int j = 0;

    Vec3f intensity;
    cv::Mat imageF;
    cv::Mat image;
    imageF= cv::Mat::zeros(36,36,CV_32FC3);

    for(j=0; j<imageF.cols; ++j) {
        for(i=0; i<imageF.rows; ++i) {
            intensity = imageF.at<Vec3f>(j, i);
            intensity.val[2] = 0.789347;
            intensity.val[1] = 0.772673;
            intensity.val[0] = 0.692689;
            imageF.at<Vec3f>(j, i) = intensity;
            }
        }

    imshow("Output", imageF);

    Mat3b imageF_8UC3;
    imageF.convertTo(imageF_8UC3, CV_8UC3, 255);
    imwrite("test.png", imageF_8UC3);

    waitKey(0);
    return 0;
    }

正如您在文檔中所讀到的:

函數 imwrite 將圖像保存到指定的文件中。 圖像格式是根據文件擴展名選擇的(有關擴展名列表,請參閱 imread())。 使用此功能只能保存 8 位(或 16 位無符號 (CV_16U),對於 PNG、JPEG 2000 和 TIFF)單通道或 3 通道(具有“BGR”通道順序)圖像。 如果格式、深度或通道順序不同,請在保存前使用 Mat::convertTo() 和 cvtColor() 進行轉換。

您應該使用convertToCV_32FC3轉換為CV_8UC3以獲得相同的結果:

Mat3b imageF_8UC3;
imageF.convertTo(imageF_8UC3, CV_8UC3, 255);
imwrite("test.png", imageF_8UC3);

順便說一句, imshow()顯示正確,因為...

  • 如果圖像是 8 位無符號,則按原樣顯示。
  • 如果圖像是 16 位無符號或 32 位整數,則將像素除以 256。即值范圍 [0,255*256] 映射到 [0,255]。
  • 如果圖像是 32 位浮點數,則像素值乘以 255。即值范圍 [0,1] 映射到 [0,255]。

基本上,同樣的技巧是你在寫作之前需要做的。

我來到這個問題,因為我也有黑色“.png”圖像的問題。 最終我意識到,我的帶有通道(紅色、綠色、藍色、Alpha)的 32 位圖像有一個零值的 Alpha 通道(完全透明)。 因此,知道透明度的程序只會顯示“圖像背后的黑色背景”。 將透明度更改為“255”(無透明度)后,我保存的 png 圖像可以很好地可視化:

MyImage[:,:,3] = 255

您可以通過分配 127 的值來檢查該行為,您將獲得圖像的蒼白/灰色版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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