首先根据图片进行裁剪 得到有用的数据
1 public static int[,] RGB2Gray(Bitmap srcBitmap) 2 { 3 4 int wide = srcBitmap.Width; 5 6 int height = srcBitmap.Height; 7 8 Rectangle rect = new Rectangle(0, 0, wide, height); 9 10 // 将Bitmap锁定到系统内存中, 获得BitmapData 11 12 BitmapData srcBmData = srcBitmap.LockBits(rect, 13 14 ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 15 16 //创建Bitmap 17 18 Bitmap dstBitmap = CreateGrayscaleImage(wide, height);//这个函数在后面有定义 19 20 BitmapData dstBmData = dstBitmap.LockBits(rect, 21 22 ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); 23 24 // 位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行 25 26 System.IntPtr srcPtr = srcBmData.Scan0; 27 28 System.IntPtr dstPtr = dstBmData.Scan0; 29 30 // 将Bitmap对象的信息存放到byte数组中 31 32 int src_bytes = srcBmData.Stride * height; 33 34 byte[] srcValues = new byte[src_bytes]; 35 36 int dst_bytes = dstBmData.Stride * height; 37 38 byte[] dstValues = new byte[dst_bytes]; 39 40 //复制GRB信息到byte数组 41 42 System.Runtime.InteropServices.Marshal.Copy(srcPtr, srcValues, 0, src_bytes); 43 44 System.Runtime.InteropServices.Marshal.Copy(dstPtr, dstValues, 0, dst_bytes); 45 46 int unm = 365; 47 // 根据Y=0.299*R+0.114*G+0.587B,Y为亮度 48 int[,] imgData = new int[wide, height - 365 - 37]; 49 50 for (int i = 365; i < height - 37; i++) 51 52 for (int j = 0; j < wide; j++) 53 54 { 55 56 //只处理每行中图像像素数据,舍弃未用空间 57 58 //注意位图结构中RGB按BGR的顺序存储 59 60 int k = 3 * j; 61 62 double temp = srcValues[i * srcBmData.Stride + k + 1];// (double)(srcValues[i * srcBmData.Stride + k + 2] * .299 63 64 //+ srcValues[i * srcBmData.Stride + k + 1] * .587 + srcValues[i * srcBmData.Stride + k] * .114); 65 66 dstValues[i * dstBmData.Stride + j] = (byte)temp; 67 //imgData[j,i,0] = srcValues[i * srcBmData.Stride + k + 2]; 68 imgData[j, i - 365] = srcValues[i * srcBmData.Stride + k + 1]; 69 //imgData[j, i, 2] = srcValues[i * srcBmData.Stride + k ]; 70 } 71 72 //将更改过的byte[]拷贝到原位图 73 74 System.Runtime.InteropServices.Marshal.Copy(dstValues, 0, dstPtr, dst_bytes); 75 76 77 78 // 解锁位图 79 80 srcBitmap.UnlockBits(srcBmData); 81 82 dstBitmap.UnlockBits(dstBmData); 83 dstBitmap.Save("1.jpg"); 84 return imgData; 85 86 87 88 }//# 89 public static Bitmap CreateGrayscaleImage(int width, int height) 90 91 { 92 93 // create new image 94 95 Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed); 96 97 // set palette to grayscale 98 99 // check pixel format 100 101 if (bmp.PixelFormat != PixelFormat.Format8bppIndexed) 102 103 throw new ArgumentException(); 104 105 106 107 // get palette 108 109 ColorPalette cp = bmp.Palette; 110 111 // init palette 112 113 for (int i = 0; i < 256; i++) 114 115 { 116 117 cp.Entries[i] = Color.FromArgb(i, i, i); 118 119 } 120 121 // set palette back 122 123 bmp.Palette = cp; 124 125 // return new image 126 127 return bmp; 128 129 }//# 130
然后对其进行调用
1 private void setImgData() 2 { 3 try 4 { 5 Bitmap img = new Bitmap(imgname); 6 int wide = img.Width; 7 int height = img.Height - 365 - 37; 8 9 var data1 = RGB2Gray(img); 10 var val = CalcRec.GetLimetImage(data1, valColor, valContinuou); //返回缺陷级别 11 string isokstr = "正常"; 12 switch (val) 13 { 14 case 0: 15 isokstr = "正常"; 16 break; 17 case 1: 18 isokstr = "裂纹"; 19 break; 20 case 2: 21 isokstr = "焊缝"; 22 break; 23 default: 24 isokstr = "未知"; 25 break; 26 } 27 label_res.Text = isokstr; 28 int ii = 0; 29 30 for (int i = 0; i < wide; i++) 31 { 32 33 for (int j = 0; j < height; j++) 34 { 35 uint setColor = 0; 36 if (data1[i, j] == 0) 37 { 38 setColor = (uint)ColorTranslator.ToOle(Color.FromArgb(0, 0, 200)); 39 } 40 else 41 { 42 int color = PraseColor((data1[i, j])); 43 setColor = (uint)ColorTranslator.ToOle(Color.FromArgb(color, color, 0));// PraseColor(data1[i, j]); 44 } 45 axTChart9.Series(0).asSurface.AddXYZ(i, data1[i, j], j, "", setColor); //向Tower序列中添加数据 46 } 47 ii++; 48 if (ii > 1000) 49 { 50 ii = 0; 51 Application.DoEvents(); 52 } 53 } 54 55 56 } 57 catch (Exception pe) 58 { 59 60 throw pe; 61 } 62 } 63 64 private int PraseColor(int v) 65 { 66 int input_start = valColor; //最低数量范围的输入。 67 int input_end = 255; //最低数量范围的输入。 68 int out_start = 10; //编号最小的范围内输出。 69 int out_end = 255; //范围输出中人数最多的。INT输入= 127; //输入值。 70 int res = 0; 71 if (v > 0) 72 { 73 res = (out_start + ((out_end - out_start) / (input_end - input_start)) * (v - input_start)); 74 } 75 76 return res; 77 } 78 private float PraseColor(double v, int inputEnd) 79 { 80 float input_start = 0; //最低数量范围的输入。 81 float input_end = 5000f; //最低数量范围的输入。 82 float out_start = 0f; //编号最小的范围内输出。 83 float out_end = 255f; //范围输出中人数最多的。INT输入= 127; //输入值。 84 float res = 0; 85 if (v > 1000) 86 { 87 res = (out_start + ((out_end - out_start) / (input_end - input_start)) * ((int)v - input_start)); 88 } 89 90 return res; 91 } 92
其中关键是 这个方法 对数据进行处理 GetLimetImage 对图像的相关 R G B 中的一层进行 判断
这个方法的逻辑是
1 public static int GetLimetImage(int[,] imageGreen, int a1, int a2) 2 { 3 List<int> coumindex = new List<int>(); 4 HashSet<int> y = new HashSet<int>(); 5 for (int i = 0; i < imageGreen.GetLength(0); i++) 6 { 7 int gcontiu = 0; 8 int contiu = 0; 9 for (int j = 0; j < imageGreen.GetLength(1); j++) 10 { 11 imageGreen[i, j] = -imageGreen[i, j] + 255; 12 if (imageGreen[i, j] < a1) 13 { 14 imageGreen[i, j] = 0; 15 } 16 else 17 { 18 contiu++; 19 if (contiu == a2) 20 { 21 gcontiu++; 22 23 } 24 } 25 } 26 if (gcontiu == 0) 27 { 28 for (int k = 0; k < imageGreen.GetLength(1); k++) 29 { 30 imageGreen[i, k] = 0; 31 } 32 } 33 else 34 { 35 coumindex.Add(i); 36 for (int j = 0; j < imageGreen.GetLength(1); j++) 37 { 38 if (imageGreen[i, j] != 0) 39 { 40 y.Add(j); 41 } 42 } 43 } 44 } 45 int p = coumindex.Count >0?1:0; 46 for (int i = 0; i < coumindex.Count - 1; i++) 47 { 48 if (coumindex[i + 1] - coumindex[i] != 1) 49 { 50 p++; 51 } 52 } 53 54 var Val = 0; 55 if (coumindex.Count == 0|| y.Count==0) { 56 return Val; 57 } 58 if (p == 1) { 59 Val = 1; 60 } else { 61 long allpoint = 0; 62 int[,] allpointDel = new int[coumindex.Count, y.Count]; 63 64 for (int i = 0; i < coumindex.Count; i++) 65 { 66 for (int j = 0; j < y.Count; j++) 67 { 68 allpointDel[i, j] = imageGreen[coumindex[i], y.ElementAt(j)]; 69 allpoint = allpoint + imageGreen[coumindex[i], y.ElementAt(j)]; 70 } 71 } 72 var mevn = allpoint / (coumindex.Count * y.Count * 1.0); 73 if (mevn < 40) { 74 Val = 0; 75 } else { 76 Val = 2; 77 } 78 } 79 return Val; 80 }
上图是MatLab 的mesh 下图是 TeeChar2017
原文:https://www.cnblogs.com/mrguoguo/p/13588654.html