/// 静态函数 /// private static List <PointF> ComputeDefaultROIPoints(ushort[,] imgData) { ushort[,] imagedataTemp = (ushort[, ])imgData.Clone(); int[] rdata = LunImage.FindMaxAndMin(imagedataTemp); int maxValue = rdata[0]; int minValue = rdata[1]; int lenValue = maxValue - minValue + 1; int[] histogramData = new int[lenValue]; foreach (int da in imgData) { histogramData[da - minValue]++; } double sum = 0; double csum = 0.0; int n = 0; int thresholdValue = 0; for (int k = 0; k < lenValue; k++) { sum += (double)k * (double)histogramData[k]; /* x*f(x) 质量矩*/ n += histogramData[k]; /* f(x) 质量 */ } if (n <= 0) { // if n has no value, there is problems... return(new List <PointF>()); } // do the otsu global thresholding method double fmax = -1.0; int n1 = 0; int n2 = 0; double m1, m2 = 0; for (int k = 0; k < lenValue; k++) { n1 += histogramData[k]; if (n1 <= 0) { continue; } n2 = n - n1; if (n2 == 0) { break; } csum += (double)k * histogramData[k]; m1 = csum / n1; m2 = (sum - csum) / n2; double sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2); /* bbg: note: can be optimized. */ if (sb > fmax) { fmax = sb; thresholdValue = k; } } for (int i = 0; i < imagedataTemp.GetLength(0); i++) { for (int j = 0; j < imagedataTemp.GetLength(1); j++) { if (imagedataTemp[i, j] < thresholdValue) { imagedataTemp[i, j] = 0; } else { imagedataTemp[i, j] = (ushort)thresholdValue; } } } int level = thresholdValue / 2; int window = thresholdValue / 5; Histogram his = new Histogram(imagedataTemp); int HFMax = level + window / 2; int HFMin = level - window / 2; if (HFMax < 0 || HFMin < 0) { level = his.WinCenter; window = his.WinWidth; } else { if (HFMax > his.MaxValue || HFMin > his.MaxValue) { level = his.WinCenter; window = his.WinWidth; } } int maxvalue = his.LenValue < 256 ? 256 : his.LenValue; maxValue = maxvalue; minValue = his.MinValue; Color[] LUT = HisLUT.RefreshLUT(null, false, level, window, maxvalue, minValue); Bitmap BMP = TypeConvert.SliceImageToBitmap24(imagedataTemp, LUT, minValue); float x1 = 0; float y1 = 0; float x2 = BMP.Width - 1; float y2 = BMP.Height - 1; BoundaryTracker bt = new BoundaryTracker(); bt.GetSerializedBoundary(BMP, LUT[0], new Rectangle((int)x1, (int)y1, (int)(x2 - x1 + 1), (int)(y2 - y1 + 1)), false); List <PointF> temp = new List <PointF>(); if (bt.MaxPointIdx != -1) { PointF[] tmp = bt.CL[bt.MaxPointIdx]; if (tmp.Length > 3) { for (int i = 0; i < tmp.Length; i++) { temp.Add(tmp[i]); } } } else { temp.Add(new PointF(0, 0)); temp.Add(new PointF(0, BMP.Height - 1)); temp.Add(new PointF(BMP.Width - 1, BMP.Height - 1)); temp.Add(new PointF(BMP.Width - 1, 0)); } return(temp); }
private void ComputeDefaultROIPoints() { AverageImageObjectBase cbTemp = Clone(); ushort[,] imagedataTemp = cbTemp.imageData; int[] rdata = LunImage.FindMaxAndMin(imagedataTemp); int maxValue = rdata[0]; int minValue = rdata[1]; int lenValue = maxValue - minValue + 1; int[] histogramData = new int[lenValue]; foreach (int da in cbTemp.ImageData) { histogramData[da - minValue]++; } double sum = 0; double csum = 0.0; int n = 0; int thresholdValue = 0; for (int k = 0; k < lenValue; k++) { sum += (double)k * (double)histogramData[k]; /* x*f(x) 质量矩*/ n += histogramData[k]; /* f(x) 质量 */ } if (n <= 0) { // if n has no value, there is problems... return; } // do the otsu global thresholding method double fmax = -1.0; int n1 = 0; int n2 = 0; double m1, m2 = 0; for (int k = 0; k < lenValue; k++) { n1 += histogramData[k]; if (n1 <= 0) { continue; } n2 = n - n1; if (n2 == 0) { break; } csum += (double)k * histogramData[k]; m1 = csum / n1; m2 = (sum - csum) / n2; double sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2); /* bbg: note: can be optimized. */ if (sb > fmax) { fmax = sb; thresholdValue = k; } } for (int i = 0; i < imagedataTemp.GetLength(0); i++) { for (int j = 0; j < imagedataTemp.GetLength(1); j++) { if (imagedataTemp[i, j] < thresholdValue) { imagedataTemp[i, j] = 0; } else { imagedataTemp[i, j] = (ushort)thresholdValue; } } } cbTemp.SetLUT(null); cbTemp.level = thresholdValue / 2; cbTemp.window = thresholdValue / 5; cbTemp.ImageData = imagedataTemp; float x1 = 0; float y1 = 0; float x2 = BMP.Width - 1; float y2 = BMP.Height - 1; BoundaryTracker bt = new BoundaryTracker(); bt.GetSerializedBoundary(cbTemp.BMP, LUT[0], new Rectangle((int)x1, (int)y1, (int)(x2 - x1 + 1), (int)(y2 - y1 + 1)), false); List <PointF> temp = new List <PointF>(); if (bt.MaxPointIdx != -1) { PointF[] tmp = bt.CL[bt.MaxPointIdx]; if (tmp.Length > 3) { for (int i = 0; i < tmp.Length; i++) { temp.Add(tmp[i]); } } } else { temp.Add(new PointF(0, 0)); temp.Add(new PointF(0, cbTemp.BMP.Height - 1)); temp.Add(new PointF(cbTemp.BMP.Width - 1, cbTemp.BMP.Height - 1)); temp.Add(new PointF(cbTemp.BMP.Width - 1, 0)); } for (int i = 0; i < temp.Count; i++) { float x = ((float)temp[i].X * (float)pixelSize); float y = ((float)temp[i].Y * (float)pixelSize); temp[i] = (new PointF(x, y)); } ROIPoints = temp; //ImageObjectBase tempcb = cb.Clone(); //RefreshROI(ref tempcb, Color.Red); //cb.showROI = true; //cb.BMP = tempcb.BMP; //loadImagebyJacbi(pictureBox1, cb.BMP, 1); }
//对所给定的图像进行边缘检测,如果对比度较大,则计算出相应外轮廓 //在ImageROI中添加相应的边界点数组,并添加相应的矩形区域选框 //检测 public void GetBoundaryOfData() { ushort[,] data = img.ImageData; int width = data.GetLength(0); int height = data.GetLength(1); int sum = 0; for (int i = width / 2 - 5; i < width / 2 + 5; i++) { for (int j = height / 2 - 5; j < height / 2 + 5; j++) { sum += data[i, j]; } } int average = sum / 100; double scale = 0.5; try { scale = double.Parse(CapturePub.readCaptrueValue("EvaluateScaleThreshold")); } catch (System.Exception ex) { scale = 0.5; } int threshold = (int)(average * scale); Bitmap bmp = (Bitmap)(img.BMP.Clone()); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (data[i, j] > threshold) { bmp.SetPixel(j, i, Color.Red); } } } BoundaryTracker bt = new BoundaryTracker(); if (bt.GetSerializedBoundary(bmp, Color.Red)) { int indexPts = 0; for (int i = 0; i < bt.CL.Count; i++) { if (bt.CL[i].Length > bt.CL[indexPts].Length) { indexPts = i; } } if (bt.CL.Count != 0) { PointF[] pts = bt.CL[indexPts]; int Xmin = int.MaxValue; int Xmax = int.MinValue; int Ymin = int.MaxValue; int Ymax = int.MinValue; for (int i = 0; i < pts.Length; i++) { if (Xmin > pts[i].X) { Xmin = (int)pts[i].X; } if (Ymin > pts[i].Y) { Ymin = (int)pts[i].Y; } if (Xmax < pts[i].X) { Xmax = (int)pts[i].X; } if (Ymax < pts[i].Y) { Ymax = (int)pts[i].Y; } } Point pt1 = new Point(Xmin, Ymin); Point pt2 = new Point(Xmax, Ymin); Point pt3 = new Point(Xmax, Ymax); Point pt4 = new Point(Xmin, Ymax); Rectangle rect = new Rectangle(pt1, new Size(Xmax - Xmin, Ymax - Ymin)); img.boundaryPoint = new List <Point>() { pt1, pt2, pt3, pt4 }; img.BoundaryRect = rect; img.ROIRectangle = rect; return; } } img.boundaryPoint = new List <Point>() { new Point(0, 0), new Point(data.GetLength(0), 0), new Point(data.GetLength(0), data.GetLength(1)), new Point(0, data.GetLength(1)) }; img.BoundaryRect = new Rectangle(new Point(0, 0), new Size(data.GetLength(0), data.GetLength(1))); img.ROIRectangle = img.BoundaryRect; return; }