/// <summary> /// 计算图像的直方图 /// </summary> private void ComputeHistogram(ushort[,] data) { if (data == null) { lenValue = 0; histogramData = null; return; } int[] rdata = LunImage.FindMaxAndMin(data); maxValue = rdata[0]; minValue = rdata[1]; lenValue = maxValue - minValue + 1; histogramData = new int[lenValue]; foreach (int e in data) { histogramData[e - minValue]++; } //均值法 int all = data.Length; all = all - histogramData[0] - histogramData[lenValue - 1]; //避免直方图首尾值太大影响显示比例. histogramData[0] = 0; histogramData[maxValue - minValue] = 0; const float factor = 2;//修正参数 numMostValue = (int)(all * factor / lenValue + 0.5); ComputeDefaultLW(); }
private void RefreshROI(ref AverageImageObjectBase cImage, Color fillCL) { if (cImage == null || cImage.ROIPoints == null || cImage.ROIPoints.Count <= 0) { return; } int[] pt = LunImage.FindMaxAndMin(cImage.imageData); int minV = pt[1]; List <PointF> temp = GetROIPoint(cImage); Bitmap bm = (Bitmap)(cImage.BMP.Clone()); Graphics g = Graphics.FromImage(bm); Brush brush = new SolidBrush(fillCL);//Color.Red); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.FillPolygon(brush, temp.ToArray(), System.Drawing.Drawing2D.FillMode.Alternate); g.Dispose(); Bitmap btpb = (Bitmap)(cImage.BMP); int H = cImage.ImageData.GetLength(0); int W = cImage.ImageData.GetLength(1); System.Drawing.Imaging.BitmapData bmpData = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bm.PixelFormat); System.IntPtr bmDataScan = bmpData.Scan0; int bmStride = bmpData.Stride; int Offset = bmStride - bm.Width * 3; unsafe { try { int clR = fillCL.R; int clG = fillCL.G; int clB = fillCL.B; byte *bmPtr = (byte *)(void *)bmDataScan; for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) { if (!(bmPtr[0] == clB && bmPtr[1] == clG && bmPtr[2] == clR)) { cImage.imageData[y, x] = (ushort)minV; } bmPtr += 3; } } } catch { bm.UnlockBits(bmpData); return; } } bm.UnlockBits(bmpData); cImage.BMP = TypeConvert.SliceImageToBitmap24(cImage.imageData, cImage.LUT, cImage.minValue); //histogramControl1.RefreshHistogram(cImage.imageData); }
private static ushort[,] GetROIImageData(ushort[,] imgData, List <PointF> points_ROI, Color fillCL) { if (points_ROI == null || points_ROI.Count <= 0) { return(imgData); } int[] pt = LunImage.FindMaxAndMin(imgData); int minV = pt[1]; int H = imgData.GetLength(0); int W = imgData.GetLength(1); Bitmap bm = new Bitmap(W, H, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(bm); Brush brush = new SolidBrush(fillCL);//Color.Red); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.FillPolygon(brush, points_ROI.ToArray(), System.Drawing.Drawing2D.FillMode.Alternate); g.Dispose(); BitmapData bmpData = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite, bm.PixelFormat); System.IntPtr bmDataScan = bmpData.Scan0; int bmStride = bmpData.Stride; int Offset = bmStride - bm.Width * 3; unsafe { try { int clR = fillCL.R; int clG = fillCL.G; int clB = fillCL.B; byte *bmPtr = (byte *)(void *)bmDataScan; for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) { if (!(bmPtr[0] == clB && bmPtr[1] == clG && bmPtr[2] == clR)) { imgData[y, x] = (ushort)minV; } bmPtr += 3; } } } catch { bm.UnlockBits(bmpData); } } bm.UnlockBits(bmpData); return(imgData); }
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); }
public static ushort[,] CLAHE(string strength, ushort[,] image) { if (strength == "") { return(image); } string[] claheStr = strength.Split('$'); if (claheStr.Length <= 1) { return(image); } string[] temp = (claheStr[0]).Split('\\'); if (temp.Length <= 1 || (temp.Length > 1 && temp[0] == "") || (temp.Length > 1 && temp[0] == "Clahe,No Process")) { return(image); } //try //{ // int model = int.Parse(temp[0]); //} //catch (System.Exception ex) //{ // return image; //} try { string[] paras = temp[1].Split(','); ushort[,] img = (ushort[, ])(image.Clone()); int uiXRes = image.GetLength(0); int uiYRes = image.GetLength(1); int[] maxmin = LunImage.FindMaxAndMin(image); ushort[] cArray = new ushort[uiXRes * uiYRes]; for (int i = 0; i < uiXRes; ++i) { int it = i * uiYRes; for (int j = 0; j < uiYRes; ++j) { cArray[it + j] = image[i, j]; } } int Min = maxmin[1]; int Max = maxmin[0]; int uiNrBins = int.Parse(paras[2]); int uiNrX = int.Parse(paras[0]); int uiNrY = int.Parse(paras[1]); float fCliplimit = float.Parse(paras[3]); int cla = CLAHE(cArray, uiXRes, uiYRes, Min, Max, uiNrX, uiNrY, uiNrBins, fCliplimit); for (int i = 0; i < uiXRes; ++i) { int it = i * uiYRes; for (int j = 0; j < uiYRes; ++j) { img[i, j] = (ushort)cArray[it + j]; } } return(img); } catch (System.Exception ex) { return(image); } }
/// 静态函数 /// 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); }