Ejemplo n.º 1
0
        /// <summary>
        /// 位置检查图比较相似度
        /// </summary>
        /// <param name="dataElem">预先设定好的数据对象</param>
        /// <param name="excsd">期望相似度</param>
        /// <returns></returns>
        private bool RealTimeSynCheckPositionContrast(DataElem dataElem, int excsd = 12)
        {
            var bitmap    = BasicMethodClass.GetWindowCapture(configData.Hwnd);
            var cutbitmap = BasicMethodClass.CutImage(bitmap, dataElem.SynCheckPosition);

            bitmap.Dispose(); bitmap = null;

            int csd = BasicMethodClass.SimilarPhoto.CalcSimilarDegree(cutbitmap, dataElem.SynCheckImage);

            if (dataElem.curComparisonImage1 != null)
            {
                dataElem.curComparisonImage1.Dispose();
                dataElem.curComparisonImage1 = null;
            }
            if (dataElem.curComparisonImage2 != null)
            {
                dataElem.curComparisonImage2.Dispose();
                dataElem.curComparisonImage1 = null;
            }
            dataElem.curComparisonImage1 = cutbitmap;
            dataElem.curComparisonImage2 = new System.Drawing.Bitmap(dataElem.SynCheckImage);
            //  if (bitmap!=null)
            //      bitmap.Dispose();
            //   if (cutbitmap != null)
            //       cutbitmap.Dispose();
            return(csd < excsd);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 获取歌曲中前1Mbt中包含的图片,并返回
        /// </summary>
        public BitmapImage GetJPGFromStream(SongInfo songInfo, int PixelWidth = 0, int PixelHeight = 0)
        {
            MemoryStream ms = null;

            try
            {
                BitmapImage image  = new BitmapImage();
                byte[]      buffer = GetJPGBuffer(songInfo, 10240);
                if (buffer != null)
                {
                    ms = new MemoryStream(buffer);
                }
                image.BeginInit();
                image.CacheOption  = BitmapCacheOption.OnLoad;
                image.StreamSource = ms;
                try
                {
                    try
                    {
                        image.EndInit();
                    }
                    catch (NotSupportedException)
                    {
                        MemoryStream saveStream = new MemoryStream();
                        if (!BasicMethodClass.MakeThumbnail(ms, saveStream, 602, 602, "W", "jpg"))
                        {
                            return(null);
                        }
                        saveStream.Seek(0, SeekOrigin.Begin);
                        image.BeginInit();
                        image.CacheOption  = BitmapCacheOption.OnLoad;
                        image.StreamSource = saveStream;
                        image.EndInit();
                        saveStream.Dispose();
                    }
                }
                catch (Exception)
                {
                    return(null);
                }

                if (PixelWidth != 0)
                {
                    image.DecodePixelWidth = PixelWidth;
                }
                if (PixelHeight != 0)
                {
                    image.DecodePixelHeight = PixelHeight;
                }

                return(image);
            }
            catch { return(null); }
            finally {
                if (ms != null)
                {
                    ms.Dispose();
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        ///  实现功能: 基于Frequency-tuned 的图像显著性检测
        ///    参考论文: Frequency-tuned Salient Region Detection, Radhakrishna Achantay, Page 4-5, 2009 CVPR
        ///               http://ivrgwww.epfl.ch/supplementary_material/RK_CVPR09/
        ///    参考论文作者RGB转LAB的浮点版本
        /// </summary>
        /// <param name="srcBitmap"></param>
        /// <returns></returns>
        public static Bitmap SalientRegionDetectionBasedOnFT(Bitmap srcBitmap)
        {
            int        width = srcBitmap.Width, height = srcBitmap.Height;
            Rectangle  rect      = new Rectangle(0, 0, width, height);
            BitmapData srcBmData = srcBitmap.LockBits(rect,
                                                      ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            Bitmap     dstBitmap = BasicMethodClass.CreateGrayscaleImage(width, height);
            BitmapData dstBmData = dstBitmap.LockBits(rect,
                                                      ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

            IntPtr srcScan = srcBmData.Scan0;
            IntPtr dstScan = dstBmData.Scan0;

            unsafe
            {
                double * srcP = (double *)(void *)srcScan;
                byte *   dstP = (byte *)(void *)dstScan;
                int      Index = 0, CurIndex = 0, srcStride = srcBmData.Stride, dstStride = dstBmData.Stride, X, Y;
                double   MeanL = 0, MeanA = 0, MeanB = 0;
                double[] LabF;
                double[] DistMap = new double[dstStride * height];
                LabF = BasicMethodClass.sRGBtoXYZ(srcBmData, width, height, out MeanL, out MeanA, out MeanB);
                //     LabF = BasicMethodClass.GaussianSmooth(LabF, width, srcBmData.Stride, srcBmData.Height);
                double maxval = 0;
                double minval = double.MaxValue;
                int    i      = 0;
                for (Y = 0; Y < height; Y++)
                {
                    Index = Y * srcStride;

                    CurIndex = Y * dstStride;   //
                    for (X = 0; X < width; X++) //    计算像素的显著性
                    {                           //此处有时会出现数组越界,原因暂时未知(已解决,目标8位图有3字节的对齐)
                        double curValue = (MeanL - LabF[Index]) * (MeanL - LabF[Index]) + (MeanA - LabF[Index + 1]) * (MeanA - LabF[Index + 1]) + (MeanB - LabF[Index + 2]) * (MeanB - LabF[Index + 2]);
                        DistMap[CurIndex] = curValue;
                        Index            += 3;
                        CurIndex++;
                        if (maxval < curValue)
                        {
                            maxval = curValue;
                        }
                        if (minval > curValue)
                        {
                            minval = curValue;
                        }
                        i++;
                    }
                }
                BasicMethodClass.Normalize(DistMap, dstBmData.Stride, height, maxval, minval, dstP);
                //写入序列化函数中。。
            }
            srcBitmap.UnlockBits(srcBmData);
            dstBitmap.UnlockBits(dstBmData);
            return(dstBitmap);
        }
Ejemplo n.º 4
0
        public static CutImageClass MakeCutBitmap(this CutImageClass cutImageClass)
        {
            if (cutImageClass.CurDestBitmap == null)//如果CurDestBitmap没数据将直接使用亮度数据
            {
                cutImageClass.CurDestBitmap = BasicMethodClass.RGB2Gray(cutImageClass.srcBitmap);
            }
            int        width = cutImageClass.CurDestBitmap.Width, height = cutImageClass.CurDestBitmap.Height;
            Rectangle  rect = new Rectangle(0, 0, width, height);
            BitmapData VisualAttentionBmData = cutImageClass.CurDestBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

            cutImageClass.FindArea(VisualAttentionBmData);
            cutImageClass.CurDestBitmap.UnlockBits(VisualAttentionBmData);
            cutImageClass.GCSsimp_getLightRegionFromSource(cutImageClass.srcBitmap);
            return(cutImageClass);
        }
Ejemplo n.º 5
0
        public static Bitmap SalientRegionDetectionBasedOnFT(Bitmap srcBitmap, float distcof)
        {
            int        width = srcBitmap.Width, height = srcBitmap.Height;
            Rectangle  rect      = new Rectangle(0, 0, width, height);
            BitmapData srcBmData = srcBitmap.LockBits(rect,
                                                      ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            Bitmap     dstBitmap = BasicMethodClass.CreateGrayscaleImage(width, height);
            BitmapData dstBmData = dstBitmap.LockBits(rect,
                                                      ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

            IntPtr srcScan = srcBmData.Scan0;
            IntPtr dstScan = dstBmData.Scan0;

            unsafe
            {
                double * srcP = (double *)(void *)srcScan;
                byte *   dstP = (byte *)(void *)dstScan;
                int      Index = 0, CurIndex = 0, srcStride = srcBmData.Stride, dstStride = dstBmData.Stride, X, Y;
                double   MeanL = 0, MeanA = 0, MeanB = 0;
                double[] LabF;
                double[] DistMap = new double[dstStride * height];
                LabF = BasicMethodClass.sRGBtoXYZ(srcBmData, width, height, out MeanL, out MeanA, out MeanB);
                //     LabF = BasicMethodClass.GaussianSmooth(LabF, width, srcBmData.Stride, srcBmData.Height);

                //加入显著位置权重
                int wk = (int)(width / 2), hk = (int)(height / 2);

                for (Y = 0; Y < height; Y++)
                {
                    Index = Y * srcStride;

                    CurIndex = Y * dstStride;   //
                    for (X = 0; X < width; X++) //    计算像素的显著性
                    {                           //此处有时会出现数组越界,原因暂时未知(已解决,目标8位图有3字节的对齐)
                        DistMap[CurIndex]  = (MeanL - LabF[Index]) * (MeanL - LabF[Index]) + (MeanA - LabF[Index + 1]) * (MeanA - LabF[Index + 1]) + (MeanB - LabF[Index + 2]) * (MeanB - LabF[Index + 2]);
                        DistMap[CurIndex] *= Math.Max(1 - (Math.Abs(wk - X) + Math.Abs(hk - Y)) / (wk + hk + 1.0), distcof);
                        Index             += 3;
                        CurIndex++;
                    }
                }
                DistMap = BasicMethodClass.Normalize(DistMap, dstBmData.Stride, height, dstP);
                //写入序列化函数中。。
            }
            srcBitmap.UnlockBits(srcBmData);
            dstBitmap.UnlockBits(dstBmData);
            return(dstBitmap);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 测试高斯模糊和RGB转LAB
        /// </summary>
        /// <param name="srcBitmap"></param>
        /// <returns></returns>
        public static Bitmap TestGaussianSmooth(Bitmap srcBitmap)
        {
            int        width = srcBitmap.Width, height = srcBitmap.Height;
            Rectangle  rect      = new Rectangle(0, 0, width, height);
            BitmapData srcBmData = srcBitmap.LockBits(rect,
                                                      ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            Bitmap     dstBitmap = new Bitmap(width, height);
            BitmapData dstBmData = dstBitmap.LockBits(rect,
                                                      ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            IntPtr srcScan = srcBmData.Scan0;
            IntPtr dstScan = dstBmData.Scan0;

            unsafe
            {
                double * srcP = (double *)(void *)srcScan;
                byte *   dstP = (byte *)(void *)dstScan;
                int      Index = 0, CurIndex = 0, srcStride = srcBmData.Stride, dstStride = dstBmData.Stride, X, Y;
                double   MeanL = 0, MeanA = 0, MeanB = 0;
                double[] LabF;
                LabF = BasicMethodClass.sRGBtoXYZ(srcBmData, width, height, out MeanL, out MeanA, out MeanB);
                LabF = BasicMethodClass.GaussianSmooth(LabF, width, srcBmData.Stride, srcBmData.Height);
                for (Y = 0; Y < height; Y++)
                {
                    Index = Y * srcStride;

                    CurIndex = Y * dstStride;
                    for (X = 0; X < width; X++)
                    {
                        double R, G, B;
                        Lab2RGB(LabF[Index], LabF[Index + 1], LabF[Index + 2], out R, out G, out B);
                        dstP[CurIndex]     = (byte)R;
                        dstP[CurIndex + 1] = (byte)G;
                        dstP[CurIndex + 2] = (byte)B;

                        Index    += 3;
                        CurIndex += 3;
                    }
                }
                srcBitmap.UnlockBits(srcBmData);
                dstBitmap.UnlockBits(dstBmData);
                return(dstBitmap);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 获取显著图片
        /// </summary>
        /// <param name="filepath">图片文件流</param>
        /// <param name="prewidth">预处理后的宽</param>
        /// <param name="preheight">预处理后的高</param>
        /// <param name="premode">预处理时的压缩方式</param>
        /// <param name="pretype">预处理图片后的类型</param>
        /// <param name="R">最终切割大小</param>
        /// <param name="Tolerance">切割阙值(切图时判断是否连续的亮度边界,越大越严格)</param>
        /// <returns></returns>
        public Bitmap GetSRDFromStream(Stream InImageStream,
                                       double prewidth, double preheight, string premode, string pretype,
                                       Rectangle R,
                                       int Tolerance = 200)
        {
            if (R == null)
            {
                R = new System.Drawing.Rectangle(0, 0, 256, 256);
            }
            MemoryStream ms_out    = new MemoryStream();
            Bitmap       Srcbitmap = new Bitmap(InImageStream);

            //压缩尺寸以加快速度
            BasicMethodClass.MakeThumbnail(Srcbitmap, ms_out, Math.Min(prewidth, Srcbitmap.Width), Math.Min(preheight, Srcbitmap.Height), premode, pretype);
            if (InImageStream == null)
            {
                throw new Exception("not expectation result");
            }
            if (ms_out == null)
            {
                return(null);
            }
            var vdcSrcBitmap = new Bitmap(ms_out);

            ms_out.Dispose();

            var vdcmap = VisualAttentionDetectionClass.SalientRegionDetectionBasedOnFT(vdcSrcBitmap);

            if (R.Width > Srcbitmap.Width || R.Height > Srcbitmap.Height)
            {//格式化输出图片尺寸
                ms_out = new MemoryStream();
                BasicMethodClass.MakeThumbnail(Srcbitmap, ms_out, R.Width, R.Height, premode, pretype);
                Srcbitmap.Dispose();
                Srcbitmap = new Bitmap(ms_out);
                ms_out.Dispose();
            }
            CutImageClass cuter      = new CutImageClass(vdcmap, R, Tolerance);
            var           GenerImage = cuter.GCSsimp_getLightPointFromSource(Srcbitmap);

            vdcSrcBitmap.Dispose();
            vdcmap.Dispose();
            Srcbitmap.Dispose();

            return(GenerImage);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 获取主色调
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static Color GetMajorColor(Bitmap bitmap)
        {
            Rectangle R;

            R = new System.Drawing.Rectangle(0, 0, 256, 256);
            MemoryStream ms_out = new MemoryStream();

            BasicMethodClass.MakeThumbnail(bitmap, ms_out, 600, 200, "W", "jpg");
            var srcBitmap = new Bitmap(ms_out);


            //var DH = new DominantHue(srcBitmap).GetDominantHue(0.5, 0.65, 210);
            var DH = new DominantHue(srcBitmap).GetDominantHue(0.4, 0.55, 50);

            ms_out.Dispose();
            srcBitmap.Dispose();
            return(DH);
        }
Ejemplo n.º 9
0
        public static CutImageClass MakeThumbnail(this CutImageClass cutImageClass, int width, int height, string mode = "W")
        {
            if (cutImageClass.CurDestBitmap == null)
            {
                cutImageClass.CurDestBitmap = BasicMethodClass
                                              .MakeThumbnail(cutImageClass.srcBitmap, width, height, mode, "jpg");
            }
            else
            {
                cutImageClass.CurDestBitmap = BasicMethodClass
                                              .MakeThumbnail(cutImageClass.CurDestBitmap, width, height, mode, "jpg");
            }

            cutImageClass.curDestImageWidth  = cutImageClass.CurDestBitmap.Width;
            cutImageClass.curDestImageHeight = cutImageClass.CurDestBitmap.Height;

            //mss.Dispose();
            return(cutImageClass);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// 获取一个最具显著性的源区域
        /// </summary>
        /// <param name="FinSourceImage">源图</param>
        /// <returns></returns>
        public Bitmap GCSsimp_getLightRegionFromSource(Bitmap FinSourceImage)
        {
            int        DistWidth  = CutRect.Width;
            int        DistHeight = CutRect.Height;
            BitmapData srcBmData  = CurDestBitmap.LockBits(new Rectangle(0, 0, curDestImageWidth, curDestImageHeight),
                                                           ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
            IntPtr srcScan = srcBmData.Scan0;

            unsafe
            {
                srcP = (byte *)srcScan;
                int index = 0;
                if (fx == null)
                {
                    FindArea(srcBmData);
                }
                // if (MaxAreaArrValue == 0) throw new ArgumentException("Tolerance过低");
                int x_start = curDestImageWidth, x_end = 0, y_start = curDestImageHeight, y_end = 0;
                for (int y = 1; y < curDestImageHeight - 1; y++)
                {
                    index = y * srcBmData.Stride;
                    for (int x = 1; x < curDestImageWidth - 1; x++)
                    {
                        int Sx = fx[index].AreaNum;
                        //  if (Sx != 0) throw new Exception();
                        if (Sx == MAXAreaArrNumbler)
                        {
                            if (x_start > fx[index].point.X)
                            {
                                x_start = fx[index].point.X;
                            }
                            if (x_end < fx[index].point.X)
                            {
                                x_end = fx[index].point.X;
                            }
                            if (y_start > fx[index].point.Y)
                            {
                                y_start = fx[index].point.Y;
                            }
                            if (y_end < fx[index].point.Y)
                            {
                                y_end = fx[index].point.Y;
                            }
                        }
                        index++;
                    }
                }
                double _xm = (x_end + x_start) / 2.0;
                double _ym = (y_end + y_start) / 2.0;
                double _xs, _ys, _xe, _ye;
                double FinWidth = FinSourceImage.Width, FinHeight = FinSourceImage.Height;
                //projection by ratio
                _xm = _xm * FinWidth / curDestImageWidth;
                _ym = _ym * FinHeight / curDestImageHeight;
                //get rect of objective
                _xs = _xm - DistWidth / 2.0;
                _xe = _xm + DistWidth / 2.0;
                _ys = _ym - DistHeight / 2.0;
                _ye = _ym + DistHeight / 2.0;
                //cliping by rect
                if (_xs < 0)
                {
                    _xe += -_xs;
                    _xs  = 0;
                    if (_xe > FinWidth + 0.01)
                    {
                        throw new ArgumentException("cutting size is larger than source map");
                    }
                }
                else if (_xe > FinWidth)
                {
                    _xs -= _xe - FinWidth;
                    _xe  = FinWidth;
                    if (_xs < -0.01)
                    {
                        throw new ArgumentException("cutting size is larger than source map");
                    }
                }

                if (_ys < 0)
                {
                    _ye += -_ys;
                    _ys  = 0;
                    if (_ye > FinHeight + 0.01)
                    {
                        throw new ArgumentException("cutting size is larger than source map");
                    }
                }
                else if (_ye > FinHeight)
                {
                    _ys -= _ye - FinHeight;
                    _ye  = FinHeight;
                    if (_ys < -0.01)
                    {
                        throw new ArgumentException("cutting size is larger than source map");
                    }
                }

                CurDestBitmap.UnlockBits(srcBmData);
                CurDestBitmap.Dispose();
                CurDestBitmap = BasicMethodClass.CutImage(FinSourceImage, (int)_xs, (int)_ys, (int)_xe - (int)_xs, (int)_ye - (int)_ys);
            }
            return(CurDestBitmap);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// 实现功能: saliency is determined as the local contrast of an image region with respect to its neighborhood at various scales
        /// 参考论文: Salient Region Detection and Segmentation   Radhakrishna Achanta, Francisco Estrada, Patricia Wils, and Sabine SÄusstrunk   2008  , Page 4-5
        /// 参考laviewpbt的C实现 http://blog.csdn.net/laviewpbt/article/details/38357017
        /// </summary>
        /// <param name="srcBitmap"></param>
        /// <returns></returns>
        public static Bitmap SalientRegionDetectionBasedonLC(Bitmap srcBitmap)
        {
            int        width = srcBitmap.Width, height = srcBitmap.Height;
            Rectangle  rect      = new Rectangle(0, 0, width, height);
            BitmapData srcBmData = srcBitmap.LockBits(rect,
                                                      ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            Bitmap     dstBitmap = BasicMethodClass.CreateGrayscaleImage(width, height);
            BitmapData dstBmData = dstBitmap.LockBits(rect,
                                                      ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

            IntPtr srcScan = srcBmData.Scan0;
            IntPtr dstScan = dstBmData.Scan0;

            unsafe
            {
                byte *srcP = (byte *)(void *)srcScan;
                byte *dstP = (byte *)(void *)dstScan;
                int   Value;

                int   DistMaxValue = 0;                   //用于记录最大距离,用于最后归纳图片的有效颜色范围
                int   IndexBit, CurIndex;                 //用于定位字节位和像素位置
                int[] Gray     = new int[width * height]; //用于保存计算完成了的灰度值
                int[] HistGram = new int[256];            //用于直方图统计
                int[] Dist     = new int[256];            //用于记录每种颜色到各个颜色的距离
                //int[] DistMap = new int[width*height];//显著性图

                //创建直方图和灰度图
                for (int y = 0; y < height; y++)
                {
                    IndexBit = srcBmData.Stride * y;
                    CurIndex = width * y;
                    for (int x = 0; x < width; x++)
                    {
                        Value = (srcP[IndexBit] + srcP[IndexBit + 1] * 2 + srcP[IndexBit + 2]) / 4;
                        HistGram[Value]++;
                        Gray[CurIndex] = Value;
                        IndexBit      += 3;
                        CurIndex++;
                    }
                }
                //记录颜色距离
                for (int Y = 0; Y < 256; Y++)
                {
                    Value = 0;
                    for (int X = 0; X < 256; X++)
                    {
                        Value += Math.Abs(Y - X) * HistGram[X];//Y点灰度与整张图的距离
                    }
                    Dist[Y] = Value;
                    if (DistMaxValue < Value)
                    {
                        DistMaxValue = Value;
                    }
                }

                //计算用于减小距离为有效颜色值的倍数
                DistMaxValue = DistMaxValue / 256;

                //计算显著性图片
                for (int Y = 0; Y < height; Y++)
                {
                    CurIndex = Y * width;
                    IndexBit = Y * dstBmData.Stride;
                    for (int X = 0; X < width; X++)
                    {
                        Value          = Dist[Gray[CurIndex]]; //    计算全图每个像素的显著性
                        dstP[IndexBit] = (byte)(Value / DistMaxValue);
                        CurIndex++;
                        IndexBit++;
                    }
                }
            }
            srcBitmap.UnlockBits(srcBmData);
            dstBitmap.UnlockBits(dstBmData);
            return(dstBitmap);
        }
        /// <summary>
        /// 素描
        /// </summary>
        /// <param name="SourceBmp">原图</param>
        /// <param name="Contrast">预置对比度</param>
        /// <param name="Brightness">预置明度</param>
        /// <param name="MaxGrayVlue">生成图的最大灰度(色度)值</param>
        /// <param name="IsGray">是否生成灰度图</param>
        /// <remarks>注意应该从返回中取结果,而不是形参中,因为输入图引用有可能已经改变</remarks>
        static public Bitmap Sketch(Bitmap SourceBmp, double Contrast = 0.1, double Brightness = 0, byte MaxGrayVlue = 70, bool IsGray = true)
        {
            int  X, Y;
            int  SourceWidth, SourceHeight, SourceStride, DestStride, DestHeight;
            int  SourceYIndex, DestYindex, SpeedTwo, SpeedThree;
            int  BlueOne, BlueTwo, GreenOne, GreenTwo, RedOne, RedTwo;
            int  PowerRed, PowerGreen, PowerBlue;
            byte B, G, R;

            if (SourceBmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
            {
                SourceBmp = BasicMethodClass.ConverImageTo24bit(SourceBmp);
                if (SourceBmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
                {
                    throw new FormatException();
                }
            }

            byte[] SqrValue = new byte[65026];
            for (Y = 0; Y < 65026; Y++)
            {
                SqrValue[Y] = (byte)(255 - (int)Math.Sqrt(Y));                                                                            // 计算查找表,注意已经砸查找表里进行了反色
            }
            SourceWidth = SourceBmp.Width; SourceHeight = SourceBmp.Height; SourceStride = (int)((SourceBmp.Width * 3 + 3) & 0XFFFFFFFC); //gs:即使二进制的倒数第三位以后的置为0,整个数目以4的倍数递增
            DestStride  = (SourceWidth + 2) * 3; DestHeight = SourceHeight + 2;                                                           // 宽度和高度都扩展2个像素

            byte[] SourceImageData     = new byte[SourceStride * SourceHeight];                                                           // 用于保存图像数据,(处理前后的都为他)
            byte[] SourceImageDataTemp = new byte[SourceStride * SourceHeight];                                                           //用于叠加处理DestImageData
            byte[] DestImageData       = new byte[DestStride * DestHeight];                                                               // 用于保存扩展后的图像数据
            unsafe
            {
                fixed(byte *SourceP = &SourceImageData[0], SourcePT = &SourceImageDataTemp[0], DestP = &DestImageData[0], LP = &SqrValue[0])
                {
                    byte *     SourceDataP = SourceP, SourceDataPT = SourcePT, DestDataP = DestP, LutP = LP;
                    BitmapData SourceBmpData = new BitmapData();

                    SourceBmpData.Scan0  = (IntPtr)SourceDataP;//  设置为字节数组的的第一个元素在内存中的地址
                    SourceBmpData.Stride = SourceStride;
                    SourceBmp.LockBits(new System.Drawing.Rectangle(0, 0, SourceBmp.Width, SourceBmp.Height), ImageLockMode.ReadWrite | ImageLockMode.UserInputBuffer, System.Drawing.Imaging.PixelFormat.Format24bppRgb, SourceBmpData);

                    Stopwatch Sw = new Stopwatch();//  只获取计算用时

                    Sw.Start();
                    for (Y = 0; Y < SourceHeight; Y++)
                    {
                        SourceYIndex = Y * SourceStride;
                        for (X = 0; X < SourceWidth; X++)
                        {
                            //备份原图
                            SourceDataPT[SourceYIndex]     = SourceDataP[SourceYIndex];
                            SourceDataPT[SourceYIndex + 1] = SourceDataP[SourceYIndex + 1];
                            SourceDataPT[SourceYIndex + 2] = SourceDataP[SourceYIndex + 2];
                            //调节对比度
                            SourceDataP[SourceYIndex]     = (byte)Math.Min(SourceDataP[SourceYIndex] * Contrast + Brightness, 255);                 //  查表
                            SourceDataP[SourceYIndex + 1] = (byte)Math.Min(SourceDataP[SourceYIndex + 1] * Contrast + Brightness, 255);
                            SourceDataP[SourceYIndex + 2] = (byte)Math.Min(SourceDataP[SourceYIndex + 2] * Contrast + Brightness, 255);

                            SourceYIndex += 3;                                         //  跳往下一个像素
                        }
                    }
                    for (Y = 0; Y < SourceHeight; Y++)
                    {                                                                                                                                                       //拓展边缘
                        System.Buffer.BlockCopy(SourceImageData, SourceStride * Y, DestImageData, DestStride * (Y + 1), 3);                                                 // 填充扩展图的左侧第一列像素(不包括第一个和最后一个点)
                        System.Buffer.BlockCopy(SourceImageData, SourceStride * Y + (SourceWidth - 1) * 3, DestImageData, DestStride * (Y + 1) + (SourceWidth + 1) * 3, 3); // 填充最右侧那一列的数据
                        System.Buffer.BlockCopy(SourceImageData, SourceStride * Y, DestImageData, DestStride * (Y + 1) + 3, SourceWidth * 3);
                    }
                    System.Buffer.BlockCopy(DestImageData, DestStride, DestImageData, 0, DestStride);                                                //  第一行
                    System.Buffer.BlockCopy(DestImageData, (DestHeight - 2) * DestStride, DestImageData, (DestHeight - 1) * DestStride, DestStride); //  最后一行

                    for (Y = 0; Y < SourceHeight; Y++)
                    {
                        SourceYIndex = Y * SourceStride;
                        DestYindex   = DestStride * Y;
                        for (X = 0; X < SourceWidth; X++)
                        {
                            SpeedTwo   = DestYindex + DestStride;        //  尽量减少计算
                            SpeedThree = SpeedTwo + DestStride;
                            //  下面的就是严格的按照Sobel算字进行计算,代码中的*2一般会优化为移位或者两个Add指令的,如果你不放心,当然可以直接改成移位
                            RedOne = DestDataP[DestYindex]
                                     + 2 * DestDataP[SpeedTwo]
                                     + DestDataP[SpeedThree]
                                     - DestDataP[DestYindex + 6]
                                     - 2 * DestDataP[SpeedTwo + 6]
                                     - DestDataP[SpeedThree + 6];

                            GreenOne = DestDataP[DestYindex + 1]
                                       + 2 * DestDataP[SpeedTwo + 1]
                                       + DestDataP[SpeedThree + 1]
                                       - DestDataP[DestYindex + 7]
                                       - 2 * DestDataP[SpeedTwo + 7]
                                       - DestDataP[SpeedThree + 7];

                            BlueOne = DestDataP[DestYindex + 2]
                                      + 2 * DestDataP[SpeedTwo + 2]
                                      + DestDataP[SpeedThree + 2]
                                      - DestDataP[DestYindex + 8]
                                      - 2 * DestDataP[SpeedTwo + 8]
                                      - DestDataP[SpeedThree + 8];

                            RedTwo = DestDataP[DestYindex]
                                     + 2 * DestDataP[DestYindex + 3]
                                     + DestDataP[DestYindex + 6]
                                     - DestDataP[SpeedThree]
                                     - 2 * DestDataP[SpeedThree + 3]
                                     - DestDataP[SpeedThree + 6];

                            GreenTwo = DestDataP[DestYindex + 1]
                                       + 2 * DestDataP[DestYindex + 4]
                                       + DestDataP[DestYindex + 7]
                                       - DestDataP[SpeedThree + 1]
                                       - 2 * DestDataP[SpeedThree + 4]
                                       - DestDataP[SpeedThree + 7];

                            BlueTwo = DestDataP[DestYindex + 2]
                                      + 2 * DestDataP[DestYindex + 5]
                                      + DestDataP[DestYindex + 8]
                                      - DestDataP[SpeedThree + 2]
                                      - 2 * DestDataP[SpeedThree + 5]
                                      - DestDataP[SpeedThree + 8];

                            PowerRed   = RedOne * RedOne + RedTwo * RedTwo;
                            PowerGreen = GreenOne * GreenOne + GreenTwo * GreenTwo;
                            PowerBlue  = BlueOne * BlueOne + BlueTwo * BlueTwo;

                            if (PowerRed > 65025)
                            {
                                PowerRed = 65025;                  //  处理掉溢出值
                            }
                            if (PowerGreen > 65025)
                            {
                                PowerGreen = 65025;
                            }
                            if (PowerBlue > 65025)
                            {
                                PowerBlue = 65025;
                            }
                            //变亮模式叠加结果图到原图
                            R = Math.Max(LutP[PowerRed], SourceDataPT[SourceYIndex]);
                            G = Math.Max(LutP[PowerGreen], SourceDataPT[SourceYIndex]);
                            B = Math.Max(LutP[PowerBlue], SourceDataPT[SourceYIndex]);
                            if (IsGray)
                            {
                                G = (byte)(.299 * R + .587 * G + .114 * B);
                                if (G < MaxGrayVlue)
                                {
                                    G = MaxGrayVlue;
                                }
                                SourceDataP[SourceYIndex]     = G;
                                SourceDataP[SourceYIndex + 1] = G;
                                SourceDataP[SourceYIndex + 2] = G;
                            }
                            else
                            {
                                SourceDataP[SourceYIndex]     = R < MaxGrayVlue?MaxGrayVlue:R;
                                SourceDataP[SourceYIndex + 1] = G < MaxGrayVlue ? MaxGrayVlue : G;
                                SourceDataP[SourceYIndex + 2] = B < MaxGrayVlue ? MaxGrayVlue : B;
                            }

                            SourceYIndex += 3;
                            DestYindex   += 3;
                        }
                    }
                    Sw.Stop();
                    Debug.Print("计算用时: " + Sw.ElapsedMilliseconds.ToString() + " ms");

                    SourceBmp.UnlockBits(SourceBmpData);
                }
            }
            return(SourceBmp);
        }