我有一个8位灰度位图,我需要在其上进行一些模式识别。我在java中创建了第一个测试框架,它运行良好。
之后我将所有内容移植到C ++中,发现我的模式已不复存在。
经过一番调查,我意识到在java代码中有一个"隐藏"格式从TYPE_BYTE_GRAY更改为TYPE_3BYTE_BGR。
我可以将它制成以下测试功能:
public static void ConvertFiles(File dir, String format)
{
File[] images = getOrderedFiles(dir, format);
for (int i = 0; i < images.length; i++)
{
try
{
BufferedImage img = ImageIO.read(images[i]);
BufferedImage dst = new BufferedImage(img.getWidth() , img.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
for (int xTarget = 0; xTarget <img.getWidth(); xTarget++)
{
for (int yTarget = 0; yTarget <img.getHeight(); yTarget++)
{
int val = img.getRGB(xTarget, yTarget);
dst.setRGB(xTarget,yTarget, val);
}
}
ImageIO.write(dst, "bmp", new File(correctSlash(images[i].getParent()) + "Convert\\" + images[i].getName()));
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
生成的文件似乎更明亮&#34; (不能发布图片,抱歉。我可以根据要求发送它们)。当我在创建新图像时使用TYPE_BYTE_GRAY时,不会出现任何更改,因此很明显如何避免Java中的效果。
问题是现在,我喜欢&#34;更亮&#34;图像更好,想知道这里发生了什么,所以我可以将其重现为某种图像增强。
提前谢谢。答案 0 :(得分:2)
通过与同事一起挖掘java代码(getRGB())找到它(感谢Holger)。
通过查找表将转换应用于原始灰度值,生成如下:
l8Tos8 = new byte[256];
float input, output;
// algorithm for linear RGB to nonlinear sRGB conversion
// is from the IEC 61966-2-1 International Standard,
// Colour Management - Default RGB colour space - sRGB,
// First Edition, 1999-10,
// avaiable for order at http://www.iec.ch
for (int i = 0; i <= 255; i++) {
input = ((float) i) / 255.0f;
if (input <= 0.0031308f) {
output = input * 12.92f;
} else {
output = 1.055f * ((float) Math.pow(input, (1.0 / 2.4)))
- 0.055f;
}
l8Tos8[i] = (byte) Math.round(output * 255.0f);
}
至少部分伽马校正。
我可以在C ++端应用它,得到相同的结果。