/// <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); }
/// <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(); } } }
/// <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); }
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); }
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); }
/// <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); } }
/// <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); }
/// <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); }
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); }
/// <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); }
/// <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); }