好吧,所以我一直非常沮丧地尝试将12位缓冲区转换为8位缓冲区。 图像源是12位GrayScale(从JPEG2000解压缩),其颜色范围为0-4095。现在我必须将其减少到0-255。常识告诉我,我应该像这样简单地划分每个像素值。但是当我尝试这个时,图像太亮了。
void
TwelveToEightBit(
unsigned char * charArray,
unsigned char * shortArray,
const int num )
{
short shortValue = 0; //Will contain the two bytes in the shortArray.
double doubleValue = 0; //Will contain intermediary calculations.
for( int i = 0, j =0; i < num; i++, j +=2 )
{
// Bitwise manipulations to fit two chars onto one short.
shortValue = (shortArray[j]<<8);
shortValue += (shortArray[j+1]);
charArray[i] = (( unsigned char)(shortValue/16));
}
}
现在我可以说需要进行一些对比度调整。任何人的想法?
非常感谢提前
答案 0 :(得分:2)
实际上,只需要进行一些简单的对比度调整。一旦我在Photoshop中加载结果图像并进行自动对比,我就意识到了这一点......图像结果非常类似于预期的输出图像。 我找到了一个算法来做对比,并将其张贴在这里为了方便起见:
#include <math.h>
short shortValue = 0; //Will contain the two bytes in the shortBuffer.
double doubleValue = 0; //Will contain intermediary calculations.
//Contrast adjustment necessary when converting
//setting 50 as the contrast seems to be real sweetspot.
double contrast = pow( ((100.0f + 50.0f) / 100.0f), 2);
for ( int i = 0, j =0; i < num; i++, j += 2 )
{
//Bitwise manipulations to fit two chars onto one short.
shortValue = (shortBuffer[j]<<8);
shortValue += (shortBuffer[j+1]);
doubleValue = (double)shortValue;
//Divide by 16 to bring down to 0-255 from 0-4095 (12 to 8 bits)
doubleValue /= 16;
//Flatten it out from 0-1
doubleValue /= 255;
//Center pixel values at 0, so that the range is -0.5 to 0.5
doubleValue -= 0.5f;
//Multiply and just by the contrast ratio, this distances the color
//distributing right at the center....see histogram for further details
doubleValue *= contrast;
//change back to a 0-1 range
doubleValue += 0.5f;
//and back to 0-255
doubleValue *= 255;
//If the pixel values clip a little, equalize them.
if (doubleValue >255)
doubleValue = 255;
else if (doubleValue<0)
doubleValue = 0;
//Finally, put back into the char buffer.
charBuffer[i] = (( unsigned char)(doubleValue));
}
答案 1 :(得分:0)
据我所知,主要问题是将12位值转换为8位值。
Range of 12-bit value = 0 - 4095 (4096 values)
Range of 8-bit value = 0 - 255 ( 256 values)
我会尝试将12位值x
转换为8位值y
一些C-ish代码:
uint16_t x = some_value;
uint8_t y = (uint8_t) ((double) x/4096 ) * 256;
<强>更新强>
感谢Kriss的评论,我意识到我无视速度问题。由于浮动操作,上述解决方案可能比纯整数操作慢。
然后我开始考虑另一个解决方案。如何使用y
8
的最高有效位来构建x
?换句话说,通过削减4
最低有效位。
y = x >> 4;
这会有用吗?
答案 2 :(得分:0)
如果您只想删除底部的4个最低有效位,您可以执行以下操作:
unsigned int start_value = SOMEVALUE; // starting value
value = (value & 0xFF0 ); // drop bits
unsigned char final_value =(uint8_t)value >> 4; //bit shift to 8 bits
注意“未签名”。您不希望签名位与您的值混淆。
答案 3 :(得分:0)
像这样:
// Image is stored in 'data'
unsigned short* I = (unsigned short*)data;
for(int i=0; i<imageSize; i++) {
// 'color' is the 8-bit value
char color = (char)((double)(255*I[i])/(double)(1<<12));
/*...*/
}
答案 4 :(得分:-1)
狂野猜测:您的代码假设是一个大端机器(最重要的字节优先)。 Windows PC是小端的。所以也许试试
shortValue = (shortArray[j+1]<<8);
shortValue += (shortArray[j]);
如果确实是endiasness问题,那么您提供的代码只会削减每个值的4个最高位,并将其余部分扩展到强度范围。嗯,编辑,2秒后:不,那是一个思考。但是还是试试呢?
干杯&amp;第h。,
- Alf