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);
可以解释一下么?越详细,越好!!!谢谢了!

解决方案 »

  1.   

     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;
                        }
    这一段代码是获取每一个像素点的信息。读到后,gray[k]++;位于这个值增加一个。
    统计R,G,B中的颜色分布。你说的那些概念不懂,有时间就去看看文档,没时间先不用管它,可以先把东西实现了再说后面的应该就是直方图的构造了
      

  2.   


    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反而是最后一条线。
    最好你联系原作者或搜索其他代码。
    */
      

  3.   

    更正:上一贴关于bmData.Stride和 p += nOffset的评论是我的错。
    致歉!
      

  4.   

    gomoku可以说说 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;
                        }
                    } 么?谢谢!
      

  5.   

    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;
                        }
                    }
    是使用上面得到的数据来填充图像,K是像素值(0--255)newgray这个数组就存贮了0--255像素值对应的数据
    q[0] = newgray[k];这个不就把图像改变了?
    这是图像处理的一种思路,有点像调色板的应用。
    你不用管这些,先把它运行起来,有个直观上的感受,然后再去分析代码
      

  6.   

    谢谢诸位,特别谢谢gomoku (感激changjiangzhibin的指导,虽然对于我是一点用也没有,>_<)。
    还是那个问题: 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 !
      

  7.   

    1、每个象素包含RGB,红绿蓝各一个字节共3个字节。
    2、k是每个颜色的亮度,从0(全黑)到255(全亮)。 当碰到一个特定的亮度k,gray[k]++就多统计一票。最后你才能知道亮度的分布。
    3、写成 red=q[0];green=q[1]; blue=q[2];就好理解了。
    4、gray[k]的统计票可以成千上万(百万象素很普遍了),想用图像把统计结果用图形形象的表示出来,需要把它缩小到0-255的范围内。