look>> int[] gray = new int[256];
int[] gray1 = new int[256];
int[] gray2 = new int[256];
byte[] newgray = new byte[256];
byte[] newgray1 = new byte[256];
byte[] newgray2 = new byte[256];
//上面的变量有什么用?
Bitmap m_Bitmap = (Bitmap)pictureBox1.Image; int iWidth = m_Bitmap.Width;
int iHeight = m_Bitmap.Height;
long i, j, k, k1, k2;
double temp; for (i = 0; i < 256; i++)
gray[i] = 0; BitmapData bmData = m_Bitmap.LockBits(new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);//不明白作用
int stride = bmData.Stride; //不明白作用
System.IntPtr Scan0 = bmData.Scan0; //不明白作用
unsafe//这里面的大部分看不明白,对于指针是不明白,所以.....
{
byte* p = (byte*)(void*)Scan0;//变量有什么用?
byte* q = (byte*)(void*)Scan0;
int nOffset = stride - m_Bitmap.Width * 3;
for (int y = 0; y < iHeight; ++y)
{
for (int x = 0; x < iWidth; ++x)
{
k = p[0];
k1 = p[1];
k2 = p[2];
gray[k]++;
gray1[k1]++;
gray2[k2]++;
p += 3;
}
p += nOffset;
}
for (i = 0; i < 256; i++)
{
k = 0;
k1 = 0;
k2 = 0;
for (j = 0; j <= i; j++)
{
k += gray[j];
k1 += gray1[j];
k2 += gray2[j];
}
temp = Math.Round((double)(k * 255) / (iHeight * iWidth), 0);
newgray[i] = (byte)(temp);
temp = Math.Round((double)(k1 * 255) / (iHeight * iWidth), 0);
newgray1[i] = (byte)(temp);
temp = Math.Round((double)(k2 * 255) / (iHeight * iWidth), 0);
newgray2[i] = (byte)(temp);
}
for (i = 0; i < iHeight; i++)
{
for (j = 0; j < iWidth; j++)
{
k = q[0];
k1 = q[1];
k2 = q[2];
q[0] = newgray[k];
q[1] = newgray1[k1];
q[2] = newgray2[k2];
q += 3;
}
q += nOffset;
}
}
m_Bitmap.UnlockBits(bmData);
可以解释一下么?越详细,越好!!!谢谢了!
int[] gray1 = new int[256];
int[] gray2 = new int[256];
byte[] newgray = new byte[256];
byte[] newgray1 = new byte[256];
byte[] newgray2 = new byte[256];
//上面的变量有什么用?
Bitmap m_Bitmap = (Bitmap)pictureBox1.Image; int iWidth = m_Bitmap.Width;
int iHeight = m_Bitmap.Height;
long i, j, k, k1, k2;
double temp; for (i = 0; i < 256; i++)
gray[i] = 0; BitmapData bmData = m_Bitmap.LockBits(new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);//不明白作用
int stride = bmData.Stride; //不明白作用
System.IntPtr Scan0 = bmData.Scan0; //不明白作用
unsafe//这里面的大部分看不明白,对于指针是不明白,所以.....
{
byte* p = (byte*)(void*)Scan0;//变量有什么用?
byte* q = (byte*)(void*)Scan0;
int nOffset = stride - m_Bitmap.Width * 3;
for (int y = 0; y < iHeight; ++y)
{
for (int x = 0; x < iWidth; ++x)
{
k = p[0];
k1 = p[1];
k2 = p[2];
gray[k]++;
gray1[k1]++;
gray2[k2]++;
p += 3;
}
p += nOffset;
}
for (i = 0; i < 256; i++)
{
k = 0;
k1 = 0;
k2 = 0;
for (j = 0; j <= i; j++)
{
k += gray[j];
k1 += gray1[j];
k2 += gray2[j];
}
temp = Math.Round((double)(k * 255) / (iHeight * iWidth), 0);
newgray[i] = (byte)(temp);
temp = Math.Round((double)(k1 * 255) / (iHeight * iWidth), 0);
newgray1[i] = (byte)(temp);
temp = Math.Round((double)(k2 * 255) / (iHeight * iWidth), 0);
newgray2[i] = (byte)(temp);
}
for (i = 0; i < iHeight; i++)
{
for (j = 0; j < iWidth; j++)
{
k = q[0];
k1 = q[1];
k2 = q[2];
q[0] = newgray[k];
q[1] = newgray1[k1];
q[2] = newgray2[k2];
q += 3;
}
q += nOffset;
}
}
m_Bitmap.UnlockBits(bmData);
可以解释一下么?越详细,越好!!!谢谢了!
{
for (int x = 0; x < iWidth; ++x)
{
k = p[0];
k1 = p[1];
k2 = p[2];
gray[k]++;
gray1[k1]++;
gray2[k2]++;
p += 3;
}
p += nOffset;
}
这一段代码是获取每一个像素点的信息。读到后,gray[k]++;位于这个值增加一个。
统计R,G,B中的颜色分布。你说的那些概念不懂,有时间就去看看文档,没时间先不用管它,可以先把东西实现了再说后面的应该就是直方图的构造了
int[] gray = new int[256];
int[] gray1 = new int[256];
int[] gray2 = new int[256];
byte[] newgray = new byte[256];
byte[] newgray1 = new byte[256];
byte[] newgray2 = new byte[256];
//上面的变量有什么用?
/*********************************/
/* 放统计结果的(变量名称取得不好) */Bitmap m_Bitmap = (Bitmap)pictureBox1.Image;int iWidth = m_Bitmap.Width;
int iHeight = m_Bitmap.Height;
long i, j, k, k1, k2;
double temp;for (i = 0; i < 256; i++)
gray[i] = 0;
/*********************************/
/* 多此一举,已经初始化为零了 */BitmapData bmData = m_Bitmap.LockBits(new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);//不明白作
/********************************/
/* 要求准备一块24位的图像数据 */int stride = bmData.Stride; //不明白作用
/*********************************/
/* 每一扫描线的长度,由于对齐的原因 */
/* 这个长度不一定等于像素乘像素大小 */System.IntPtr Scan0 = bmData.Scan0; //不明白作用
/********************************/
/* 拿到指向准备好的像素数据块的指针 */
unsafe//这里面的大部分看不明白,对于指针是不明白,所以.....
{
byte* p = (byte*)(void*)Scan0;//变量有什么用? /*指针*/
byte* q = (byte*)(void*)Scan0;
int nOffset = stride - m_Bitmap.Width * 3; /*错误*/ for (int y = 0; y < iHeight; ++y)
{
/**************************/
/* 逐点统计RGB分值 */
for (int x = 0; x < iWidth; ++x)
{
k = p[0];
k1 = p[1];
k2 = p[2];
gray[k]++;
gray1[k1]++;
gray2[k2]++;
p += 3;
}
p += nOffset; /*错误,增量恒为3 (24bppRgb)*/ }
//...
}
m_Bitmap.UnlockBits(bmData);/*
GetPixel()和SetPixel()是个很慢的操作。拿到图像的数据直接读写可以加快很多。拿图像的数据就用到了LockBits()和bmData.Scan0
不过上述代码有错误,比如bmData.Stride可以是负数。负数的时候表示图像是由下往上排的,scan0反而是最后一条线。
最好你联系原作者或搜索其他代码。
*/
致歉!
{
k = 0;
k1 = 0;
k2 = 0;
for (j = 0; j <= i; j++)
{
k += gray[j];
k1 += gray1[j];
k2 += gray2[j];
}
temp = Math.Round((double)(k * 255) / (iHeight * iWidth), 0);
newgray[i] = (byte)(temp);
temp = Math.Round((double)(k1 * 255) / (iHeight * iWidth), 0);
newgray1[i] = (byte)(temp);
temp = Math.Round((double)(k2 * 255) / (iHeight * iWidth), 0);
newgray2[i] = (byte)(temp);
}和 for (i = 0; i < iHeight; i++)
{
for (j = 0; j < iWidth; j++)
{
k = q[0];
k1 = q[1];
k2 = q[2];
q[0] = newgray[k];
q[1] = newgray1[k1];
q[2] = newgray2[k2];
q += 3;
}
q += nOffset;
}
} 么?谢谢!
{
for (j = 0; j < iWidth; j++)
{
k = q[0];
k1 = q[1];
k2 = q[2];
q[0] = newgray[k];
q[1] = newgray1[k1];
q[2] = newgray2[k2];
q += 3;
}
q += nOffset;
}
}
是使用上面得到的数据来填充图像,K是像素值(0--255)newgray这个数组就存贮了0--255像素值对应的数据
q[0] = newgray[k];这个不就把图像改变了?
这是图像处理的一种思路,有点像调色板的应用。
你不用管这些,先把它运行起来,有个直观上的感受,然后再去分析代码
还是那个问题: 1. int nOffset = stride - m_Bitmap.Width * 3; //偏移量 为什么是 * 3?
2. 对于第一个for循环中的gray[k]++起了什么作用?
3. k = p[0];k1 = p[1]; k2 = p[2];是什么意思?
4.temp = Math.Round((double)(k * 255) / (iHeight * iWidth), 0); 这个temp是用来做什么?
这段代码就以上4个问题,解决立马给分,结贴!XD !
2、k是每个颜色的亮度,从0(全黑)到255(全亮)。 当碰到一个特定的亮度k,gray[k]++就多统计一票。最后你才能知道亮度的分布。
3、写成 red=q[0];green=q[1]; blue=q[2];就好理解了。
4、gray[k]的统计票可以成千上万(百万象素很普遍了),想用图像把统计结果用图形形象的表示出来,需要把它缩小到0-255的范围内。