簡體   English   中英

使用 stb_image 庫加載圖像作為浮點輸出錯誤值

[英]Loading image with stb_image library as float outputs wrong values

當我使用STB_Image將圖像加載為浮點數時,值似乎已關閉。 我創建了一個圖像來測試它測試圖片 . (這里使用的 RGB 代碼是 [127, 255, 32])
當我使用stbi_load()將此圖像加載為unsigned char我得到了正確的值。 但是當我使用stbi_loadf()它加載為float我得到了錯誤的值,這對我來說沒有意義。

這是我用於測試的代碼:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

#include <sstream>
#include <iomanip>
#include <iostream>
#include <string>

struct ColorF {
  float r;
  float g;
  float b;
  float a;

  std::string toString() {
    std::stringstream stream;

    stream << std::fixed << std::setprecision(2) << "[" << this->r << ", " << this->g << ", " << this->b << ", " << this->a << "]";

    return stream.str();
  }
};

struct ColorUC {
  unsigned char r;
  unsigned char g;
  unsigned char b;
  unsigned char a;

  std::string toString() {
    std::stringstream stream;

    stream << "[" << (float) this->r / 255.0f << ", " << (float) this->g / 255.0f << ", " << (float) this->b / 255.0f << ", " << (float) this->a / 255.0f << "]";

    return stream.str();
  }
};

int main() {
  int width, height, channels;
  float* image = stbi_loadf("test.png", &width, &height, &channels, STBI_rgb_alpha);

  // print content of first pixel of the image
  std::cout << ((ColorF*) image)->toString() << std::endl;

  unsigned char* jpeg = stbi_load("test.png", &width, &height, &channels, STBI_rgb_alpha);

  // print content of first pixel of the image
  std::cout << ((ColorUC*) jpeg)->toString() << std::endl;  

  stbi_image_free(image);
  stbi_image_free(jpeg);

  return 0;
}

我得到的測試輸出是這樣的:

[0.22, 1.00, 0.01, 1.00]
[0.50, 1.00, 0.13, 1.00]

從理論上講,這應該打印出相同的值,底部的值是正確的值,在兩行上,但由於某種原因它沒有。
現在我當然可以使用 unsigned char 值並為自己編寫一個函數,將所有內容轉換為正確的浮點值,但我覺得應該有一種方法可以僅使用 STB_Image 本身來做到這一點。

stb_image.h標題注釋:

// If you load LDR images through this interface, those images will
// be promoted to floating point values, run through the inverse of
// constants corresponding to the above:
//
//     stbi_ldr_to_hdr_scale(1.0f);
//     stbi_ldr_to_hdr_gamma(2.2f);

這意味着stbi_loadf()函數使用內置伽馬校正來返回其浮點值。

伽馬校正公式如下所示:

Vout = (Vin / 255)^γ; Where γ = 2.2

當你把[127, 255, 32]通過伽馬校正公式時,你會得到你看到的結果:

R: 0.22 = (127 / 255)^2.2
G: 1.00 = (255 / 255)^2.2 
B: 0.01 = ( 32 / 255)^2.2

您可以使用stbi_ldr_to_hdr_gamma(1.0f)設置 stb_image 伽馬系數作為快速修復。

但是,stb_image 專門定義了stbi_loadf()以支持非線性編碼圖像(HDR 或伽馬校正)。 如果要使用該功能加載實際的 HDR 圖像,將 gamma 設置為1.0會對繪制圖像的准確性產生負面影響; 因此,如果您確實需要使用伽馬校正加載圖像,最好只使用stbi_loadf()

現在我當然可以使用 unsigned char 值並為自己編寫一個函數,將每個值轉換為正確的浮點值,但我覺得應該有一種方法可以僅使用 STB_Image 本身來做到這一點。

使用Vout = (float)Vin / 255f手動將 8 位圖像數據轉換為浮點數明顯告訴代碼的讀者,圖像數據沒有經過伽馬校正。 stbi_loadf()stbi_ldr_to_hdr_gamma(1.0f)可能會掩蓋這一重要細節。

暫無
暫無

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

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