public static List <Mat <byte> > SplitViaOrientation(Mat <byte> src, int orientNum = 4) { int sigma = 9, lambda = 24, ksize = sigma * 6 + 1; List <Mat <double> > tmp = new List <Mat <double> >(orientNum); for (int i = 0; i < orientNum; i++) { tmp.Add(null); } Parallel.For(0, orientNum, (i) => { Mat <double> kernel = Filter.GetGaborKernel(new Size(ksize, ksize), sigma, Math.PI / orientNum * i, lambda, 1, 0); tmp[i] = ImgProc.Filter2D(src, kernel); }); List <Mat <byte> > channels = new List <Mat <byte> >(orientNum); for (int i = 0; i < orientNum; i++) { Mat <byte> channel = new Mat <byte>(src.Size); channel.Set(byte.MinValue); channels.Add(channel); } for (int i = 0; i < src.Rows; i++) { for (int j = 0; j < src.Cols; j++) { if (src[i, j] != byte.MinValue) { double maxResponse = double.MinValue; int o = -1; for (int k = 0; k < orientNum; k++) { tmp[k][i, j] = Math.Abs(tmp[k][i, j]); if (tmp[k][i, j] > maxResponse) { maxResponse = tmp[k][i, j]; o = k; } } channels[o][i, j] = src[i, j]; } } } return(channels); }
public static Mat <byte> Preprocess(Mat <byte> src, Size size, bool thinning = true) { Mat <byte> revImage = ImgProc.Reverse(src); Mat <byte> cleanedImage = BinaryImgProc.Clean(revImage, 3); Mat <byte> boundingBox = BinaryImgProc.GetBoundingBox(revImage); int widthPadding = 0, heightPadding = 0; if (boundingBox.Rows < boundingBox.Cols) { heightPadding = (boundingBox.Cols - boundingBox.Rows) / 2; } else { widthPadding = (boundingBox.Rows - boundingBox.Cols) / 2; } Mat <byte> squareImage = ImgProc.CopyMakeBorder <byte>(boundingBox, heightPadding, heightPadding, widthPadding, widthPadding, 0); Size scaledSize = new Size((int)(size.Height - 2 * size.Height / 16.0), (int)(size.Width - 2 * size.Width / 16.0)); Mat <byte> scaledImage = ImgProc.Resize(squareImage, scaledSize); heightPadding = (size.Height - scaledSize.Height) / 2; widthPadding = (size.Width - scaledSize.Width) / 2; Mat <byte> paddedImage = ImgProc.CopyMakeBorder <byte>(scaledImage, heightPadding, heightPadding, widthPadding, widthPadding, 0); Mat <byte> finalImage = paddedImage.Clone(); for (int i = 0; i < finalImage.Rows; i++) { for (int j = 0; j < finalImage.Cols; j++) { if (finalImage[i, j] > 54) { finalImage[i, j] = byte.MaxValue; } else { finalImage[i, j] = 0; } } } if (thinning) { finalImage = BinaryImgProc.Thin(finalImage); } return(finalImage); }
public static Mat <byte> Blur(Mat <byte> image, double sigma = 1.0) { Mat <double> tmp = ImgProc.Convolve2D(image, GetGaussianKernel(sigma)); Mat <byte> result = new Mat <byte>(tmp.Size); for (int i = 0; i < result.Rows; i++) { for (int j = 0; j < result.Cols; j++) { result[i, j] = (byte)tmp[i, j]; } } return(result); }
public static Tuple <Mat <double>, Mat <double> > GetGradient(Mat <byte> image, double sigma = 1.0) { Tuple <Mat <double>, Mat <double> > kernel = GetGradientKernel(sigma); Mat <double> dxImage = ImgProc.Convolve2D(image, kernel.Item1); Mat <double> dyImage = ImgProc.Convolve2D(image, kernel.Item2); Mat <double> orientImage = new Mat <double>(image.Size); for (int i = 0; i < image.Rows; i++) { for (int j = 0; j < image.Cols; j++) { double orient = Math.Atan2(dyImage[i, j], dxImage[i, j]); while (orient >= Math.PI) { orient -= Math.PI; } while (orient < 0) { orient += Math.PI; } orientImage[i, j] = orient; } } Mat <double> powerImage = new Mat <double>(image.Size); for (int i = 0; i < image.Rows; i++) { for (int j = 0; j < image.Cols; j++) { powerImage[i, j] = Math.Sqrt( dyImage[i, j] * dyImage[i, j] + dxImage[i, j] * dxImage[i, j]); } } return(Tuple.Create(powerImage, orientImage)); }