/// <summary> /// Niblackの手法による二値化処理を行う。 /// </summary> /// <param name="imgSrc">入力画像</param> /// <param name="imgDst">出力画像</param> /// <param name="kernelSize">局所領域のサイズ</param> /// <param name="k">係数</param> #else /// <summary> /// Binarizes by Niblack's method /// </summary> /// <param name="src">Input image</param> /// <param name="dst">Output image</param> /// <param name="kernelSize">Window size</param> /// <param name="k">Adequate coefficient</param> #endif public static void Niblack(IplImage src, IplImage dst, int kernelSize, double k) { if (src == null) { throw new ArgumentNullException("src"); } if (dst == null) { throw new ArgumentNullException("dst"); } // グレースケールのみ if (src.NChannels != 1) { throw new ArgumentException("src must be gray scale image"); } if (dst.NChannels != 1) { throw new ArgumentException("dst must be gray scale image"); } // サイズのチェック if (kernelSize < 3) { throw new ArgumentOutOfRangeException("kernelSize", "size must be 3 and above"); } if (kernelSize % 2 == 0) { throw new ArgumentOutOfRangeException("kernelSize", "size must be odd number"); } CvRect roi = src.ROI; int width = roi.Width; int height = roi.Height; if (width != dst.Width || height != dst.Height) { throw new ArgumentException("src.Size == dst.Size"); } unsafe { byte *pSrc = src.ImageDataPtr; byte *pDst = dst.ImageDataPtr; int stepSrc = src.WidthStep; int stepDst = dst.WidthStep; //for (int y = 0; y < gray.Height; y++) MyParallel.For(0, height, delegate(int y) { for (int x = 0; x < width; x++) { double m, s; MeanStddev(src, x + roi.X, y + roi.Y, kernelSize, out m, out s); double threshold = m + k * s; int offsetSrc = stepSrc * (y + roi.Y) + (x + roi.X); int offsetDst = stepDst * y + x; if (pSrc[offsetSrc] < threshold) { pDst[offsetDst] = 0; } else { pDst[offsetDst] = 255; } } } ); } }
/// <summary> /// Niblackの手法による二値化処理を行う。 /// </summary> /// <param name="imgSrc">入力画像</param> /// <param name="imgDst">出力画像</param> /// <param name="kernelSize">局所領域のサイズ</param> /// <param name="k">係数</param> #else /// <summary> /// Binarizes by Niblack's method /// </summary> /// <param name="src">Input image</param> /// <param name="dst">Output image</param> /// <param name="kernelSize">Window size</param> /// <param name="k">Adequate coefficient</param> #endif public static void Niblack(Mat src, Mat dst, int kernelSize, double k) { if (src == null) { throw new ArgumentNullException("src"); } if (dst == null) { throw new ArgumentNullException("dst"); } // グレースケールのみ if (src.Type() != MatType.CV_8UC1) { throw new ArgumentException("src must be gray scale image"); } if (dst.Type() != MatType.CV_8UC1) { throw new ArgumentException("dst must be gray scale image"); } // サイズのチェック if (kernelSize < 3) { throw new ArgumentOutOfRangeException("kernelSize", "size must be 3 and above"); } if (kernelSize % 2 == 0) { throw new ArgumentOutOfRangeException("kernelSize", "size must be odd number"); } int width = src.Width; int height = src.Height; dst.Create(src.Size(), src.Type()); using (var tSrcMat = new MatOfByte(src)) using (var tDstMat = new MatOfByte(dst)) { var tSrc = tSrcMat.GetIndexer(); var tDst = tDstMat.GetIndexer(); //for (int y = 0; y < gray.Height; y++) MyParallel.For(0, height, delegate(int y) { for (int x = 0; x < width; x++) { double m, s; MeanStddev(src, x, y, kernelSize, out m, out s); double threshold = m + k * s; if (tSrc[y, x] < threshold) { tDst[y, x] = 0; } else { tDst[y, x] = 255; } } } ); } }