当我处理2张灰色图像的图像倍增时,我确实看到了颜色成分。无法弄清楚到底出了什么问题:
图像: 反映图像: 上图的图像乘法:
这是我的Image Multiplicaiton函数:
public Bitmap MaskImage(Bitmap SrcBitmap1, Bitmap SrcBitmap2)
{
int width;
int height;
//Message = "Impossible.";
if (SrcBitmap1.Width < SrcBitmap2.Width)
width = SrcBitmap1.Width;
else
width = SrcBitmap2.Width;
if (SrcBitmap1.Height < SrcBitmap2.Height)
height = SrcBitmap1.Height;
else
height = SrcBitmap2.Height;
Bitmap bitmap = new Bitmap(width, height);
int clr1, clr2;
try
{
BitmapData Src1Data = SrcBitmap1.LockBits(new Rectangle(0, 0, SrcBitmap1.Width, SrcBitmap1.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
BitmapData Src2Data = SrcBitmap2.LockBits(new Rectangle(0, 0, SrcBitmap2.Width, SrcBitmap2.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
BitmapData DestData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
unsafe
{
//Following is list of offset for different bit images
//8 bit : 1
//16 bit : 2
//24 bit : 3 and
//32 bit : 4
int xOffset = 1;
for (int col = 0; col < bitmap.Height - 1; col++)
{
byte* Src1Ptr = (byte*)Src1Data.Scan0 + col * Src1Data.Stride;
byte* Src2Ptr = (byte*)Src2Data.Scan0 + col * Src2Data.Stride;
byte* DestPtr = (byte*)DestData.Scan0 + col * DestData.Stride;
for (int row = 0; row < bitmap.Width - 1; row++)
{
clr1 = (Src1Ptr[row * xOffset] + Src1Ptr[row * xOffset + 1] + Src1Ptr[row * xOffset + 2]) / 3;
clr2 = (Src2Ptr[row * xOffset] + Src2Ptr[row * xOffset + 1] + Src2Ptr[row * xOffset + 2]) / 3;
clr1 *= clr2;
if (clr1 == 0)
{
DestPtr[row * xOffset] = (byte)(0);
DestPtr[row * xOffset + 1] = (byte)(0);
DestPtr[row * xOffset + 2] = (byte)(0);
}
else
{
DestPtr[row * xOffset] = (byte)(Src2Ptr[row * xOffset]);
DestPtr[row * xOffset + 1] = (byte)(Src2Ptr[row * xOffset + 1]);
DestPtr[row * xOffset + 2] = (byte)(Src2Ptr[row * xOffset + 2]);
}
}
}
}
bitmap.UnlockBits(DestData);
SrcBitmap1.UnlockBits(Src1Data);
SrcBitmap2.UnlockBits(Src2Data);
SrcBitmap1.Dispose();
SrcBitmap2.Dispose();
}
catch (Exception ex)
{
Console.Write(ex);
}
return bitmap;
}
修改
基于Spektre代码:
问题似乎仍然是一样的。虽然我试图使用强度值而不仅仅是颜色通道:下面是代码的变化:不能真正弄清楚这里发生了什么。
输出:
public Bitmap MaskImage(Bitmap SrcBitmap1, Bitmap SrcBitmap2)
{
int width;
int height;
//Message = "Impossible.";
if (SrcBitmap1.Width < SrcBitmap2.Width)
width = SrcBitmap1.Width;
else
width = SrcBitmap2.Width;
if (SrcBitmap1.Height < SrcBitmap2.Height)
height = SrcBitmap1.Height;
else
height = SrcBitmap2.Height;
Bitmap bitmap = new Bitmap(width, height);
try
{
BitmapData Src1Data = SrcBitmap1.LockBits(new Rectangle(0, 0, SrcBitmap1.Width, SrcBitmap1.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
BitmapData Src2Data = SrcBitmap2.LockBits(new Rectangle(0, 0, SrcBitmap2.Width, SrcBitmap2.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
BitmapData DestData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
unsafe
{
//Following is list of offset for different bit images
//8 bit : 1
//16 bit : 2
//24 bit : 3 and
//32 bit : 4
int xOffset = 1;
for (int col = 0; col < bitmap.Height - 1; col++)
{
byte* Src1Ptr = (byte*)Src1Data.Scan0 + col * Src1Data.Stride;
byte* Src2Ptr = (byte*)Src2Data.Scan0 + col * Src2Data.Stride;
byte* DestPtr = (byte*)DestData.Scan0 + col * DestData.Stride;
for (int row = 0; row < bitmap.Width - 1; row++)
{
byte i1 = Src1Ptr[row * xOffset];
bbyte i2 = Src2Ptr[row * xOffset];
DestPtr[row * xOffset + 0] = (byte)((((ushort)(i1) * (ushort)(i2)) >> 8));
DestPtr[row * xOffset + 1] = (byte)((ushort)(((ushort)(i1) * (ushort)(i2)) >> 8));
DestPtr[row * xOffset + 2] = (byte)((ushort)(((ushort)(i1) * (ushort)(i2)) >> 8));
}
}
}
bitmap.UnlockBits(DestData);
SrcBitmap1.UnlockBits(Src1Data);
SrcBitmap2.UnlockBits(Src2Data);
SrcBitmap1.Dispose();
SrcBitmap2.Dispose();
}
catch (Exception ex)
{
Console.Write(ex);
}
return bitmap;
}
答案 0 :(得分:1)
关于您的代码的一些注意事项:
您的图片格式已经是8bpp,因此这里没有RGB频道:
clr1 = (Src1Ptr[row * xOffset] + Src1Ptr[row * xOffset + 1] + Src1Ptr[row * xOffset + 2]) / 3;
clr2 = (Src2Ptr[row * xOffset] + Src2Ptr[row * xOffset + 1] + Src2Ptr[row * xOffset + 2]) / 3;
因此这里不需要+1和+2,并且除以3以使图像变灰。因为输入图像已经是灰度图像。
同样,在将值分配回目标图像时,这应该足够了:
DestPtr[row * xOffset] = (byte) //value of multiplied gray level
在您的示例中,您只需返回第二个图像的值。
由于图像没有正确写入,因此生成的图像为何着色与移位(偏移,+ 1和+2)有关。
答案 1 :(得分:0)
Joel Legaspi Enriquez是对的我只想添加
R==G==B
rgb1*rgb2
乘以(3*8 + 3*8 bit result)
解决这个问题:
只增加强度
r,g,b
将输出范围归一化回原始位数
然后将结果复制到所有频道
BYTE i1=Src1Ptr[row * xOffset];
BYTE i2=Src2Ptr[row * xOffset];
DestPtr[row * xOffset+0] = BYTE(WORD((WORD(i1)*WORD(i2))>>8));
DestPtr[row * xOffset+1] = BYTE(WORD((WORD(i1)*WORD(i2))>>8));
DestPtr[row * xOffset+2] = BYTE(WORD((WORD(i1)*WORD(i2))>>8));
[EDIT1]
你的地址计算看起来很可疑
xOffset
中并且没有进一步查看address = (x*Stride)+(y*Width*stride)
col
和row
for
y
(行)和内部x
(col)