static void GenSIFT(string path, StreamWriter sw) { using (Mat input = new Mat(path, LoadMode.GrayScale)){ if (input.Empty()) { return; } double h = input.Rows, w = input.Cols; double newh, neww; if (h > w) { newh = maxSize; neww = Math.Ceiling(w / h * maxSize); } else { neww = maxSize; newh = Math.Ceiling(h / w * maxSize); } Size newsize = new Size(neww, newh); using (Mat rinput = new Mat()) { Cv2.Resize(input, rinput, newsize); using (MatOfFloat descriptors = new MatOfFloat()) { sift.Run(rinput, null, out keypoint, descriptors); var indexer = descriptors.GetIndexer(); int cnt = 0; System.Console.Out.WriteLine(descriptors.Rows); for (int i = 0; i < descriptors.Rows; i++) { String str = i.ToString(); // System.Console.Out.WriteLine(cnt); str = str + "\t0\t"; for (int j = 0; j < descriptors.Cols; j++) { str += indexer[i, j].ToString() + " "; } sw.Write(str + "\n"); cnt++; } input.Release(); rinput.Release(); descriptors.Release(); } } } }
private static void OpenCVError() { var mat = new Mat(5, 1, MatType.CV_32FC1); var mat2 = new MatOfFloat(mat); var indexer = mat2.GetIndexer(); indexer[0, 0] = 2f; indexer[1, 0] = 1f; indexer[2, 0] = 3f; indexer[3, 0] = 4f; indexer[4, 0] = 5f; double maxValue, minValue; var test = 10; int maxIdx, minIdx; Console.WriteLine(test); Cv2.MinMaxIdx(mat, out minValue, out maxValue, out minIdx, out maxIdx); Console.WriteLine(test); Console.Read(); }
private void buttonSelectImage1_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog1 = new OpenFileDialog(); if (openFileDialog1.ShowDialog() == DialogResult.OK) { try { List <OpenCvSharp.Point> rois = new List <OpenCvSharp.Point>(new OpenCvSharp.Point[] { new OpenCvSharp.Point(35, 90), new OpenCvSharp.Point(400, 90), new OpenCvSharp.Point(850, 90), new OpenCvSharp.Point(1290, 90), new OpenCvSharp.Point(35, 400), new OpenCvSharp.Point(400, 400), new OpenCvSharp.Point(850, 400), new OpenCvSharp.Point(1290, 400), new OpenCvSharp.Point(35, 800), new OpenCvSharp.Point(400, 800), new OpenCvSharp.Point(850, 800), new OpenCvSharp.Point(1290, 800), new OpenCvSharp.Point(35, 1230), new OpenCvSharp.Point(400, 1230), new OpenCvSharp.Point(850, 1230), new OpenCvSharp.Point(1290, 1230) }); var files = Directory.GetFiles(Path.GetDirectoryName(openFileDialog1.FileName), "*.png").ToList(); if (files != null && files.Count > 0) { int index = files.IndexOf(openFileDialog1.FileName); //using (var win = new Window()) //using (var win1 = new Window()) { while (true) { ListBox listBoxTemp = new ListBox(); listBoxTemp.Items.Clear(); Debug.WriteLine(files[index]); Mat img = new Mat(files[index]);//load color image Mat gray = new Mat(), laplacian = new Mat(), sobel = new Mat(), canny = new Mat(); Cv2.CvtColor(img, gray, ColorConversionCodes.BGR2GRAY); //Cv2.GaussianBlur(gray, gray, new OpenCvSharp.Size(3, 3), 0); Cv2.Canny(gray, canny, 100, 300, 3); Cv2.NamedWindow("img", WindowMode.Normal); Cv2.NamedWindow("hulls", WindowMode.Normal); Cv2.ImShow("img", img); Mat[] contours1; var hierarchy1 = new List <OpenCvSharp.Point>(); Cv2.FindContours(canny, out contours1, OutputArray.Create(hierarchy1), RetrievalModes.External, ContourApproximationModes.ApproxSimple); var hulls1 = new List <Mat>(); for (int j = 0; j < contours1.Length; j++) { Mat hull = new Mat(); Cv2.ConvexHull(contours1[j], hull); if (hull.ContourArea() > 100) { hulls1.Add(hull); } } if (hulls1.Count > 0) { Mat drawing = Mat.Zeros(canny.Size(), MatType.CV_8UC1); Cv2.DrawContours(drawing, hulls1, -1, Scalar.White, -1); Cv2.ImShow("hulls", drawing); } goto wait; Cv2.Laplacian(gray, laplacian, MatType.CV_32F); foreach (var pt in rois) { Rect roi = new Rect(pt, new OpenCvSharp.Size(200, 200)); Mat original = img.Clone(roi); Mat temp = laplacian.Clone(roi); MatOfFloat matf = new MatOfFloat(temp); var indexer = matf.GetIndexer(); List <double> sums = new List <double>(); double sum = 0; for (int y = 0; y < 25; y++) { for (int x = 0; x < 25; x++) { float val = indexer[y, x]; if (val >= 1) { sum += val; } } } sums.Add(sum); sum = 0; for (int y = 0; y < 25; y++) { for (int x = temp.Width - 25; x < temp.Width; x++) { float val = indexer[y, x]; if (val >= 1) { sum += val; } } } sums.Add(sum); sum = 0; for (int y = temp.Height - 25; y < temp.Height; y++) { for (int x = temp.Width - 25; x < temp.Width; x++) { float val = indexer[y, x]; if (val >= 1) { sum += val; } } } sums.Add(sum); sum = 0; for (int y = temp.Height - 25; y < temp.Height; y++) { for (int x = 0; x < 25; x++) { float val = indexer[y, x]; if (val >= 1) { sum += val; } } } sums.Add(sum); sum = 0; for (int y = 88; y < 113; y++) { for (int x = 88; x < 113; x++) { float val = indexer[y, x]; if (val >= 1) { sum += val; } } } sums.Add(sum); double avg = sums.Average(); double stdev = CalculateStdDev(sums); int upper = (int)(avg + 1.5 * stdev); int lower = (int)(avg - 1.5 * stdev); listBoxTemp.Items.Add(pt.ToString() + ": " + String.Join(",", sums.ToArray()) + "," + upper + "," + lower); if (sums[4] > upper || sums[4] < lower) { //Cv2.ImShow(pt.ToString(), temp); temp.ConvertTo(temp, MatType.CV_8UC1); Mat [] contours; var hierarchy = new List <OpenCvSharp.Point>(); Cv2.FindContours(temp, out contours, OutputArray.Create(hierarchy), RetrievalModes.External, ContourApproximationModes.ApproxSimple); var hulls = new List <Mat>(); for (int j = 0; j < contours.Length; j++) { Mat hull = new Mat(); Cv2.ConvexHull(contours[j], hull); if (hull.ContourArea() > 1000) { hulls.Add(hull); } } if (hulls.Count > 0) { Mat drawing = Mat.Zeros(temp.Size(), MatType.CV_8UC1); Cv2.DrawContours(drawing, contours, -1, Scalar.White, -1); Cv2.ImShow(pt.ToString() + " hulls", drawing); /* * List<OpenCvSharp.Point> points = new List<OpenCvSharp.Point>(); * foreach (Mat hull in hulls) * { * int m2Count = (hull.Rows % 2 > 0) ? hull.Rows + 1 : hull.Rows; * OpenCvSharp.Point[] p2 = new OpenCvSharp.Point[m2Count]; * hull.GetArray(0, 0, p2); * Array.Resize(ref p2, hull.Rows); * * points.AddRange(p2.ToList()); * } * Mat finalHull = new Mat(); * Cv2.ConvexHull(InputArray.Create(points), finalHull); * * if (finalHull.ContourArea() > 1000) * { * List<Mat> finalHulls = new List<Mat>(); * finalHulls.Add(finalHull); * Mat mask = Mat.Zeros(temp.Size(), MatType.CV_8UC1); * Cv2.DrawContours(mask, finalHulls, -1, Scalar.White, -1); * * Cv2.ImShow(pt.ToString(), temp); * Cv2.ImShow(pt.ToString() + " original", original); * Cv2.ImShow(pt.ToString() + " mask", mask); * //Mat masked = Mat.Zeros(original.Size(), original.Type()) ; * //masked.CopyTo(original, mask); * //Cv2.ImShow(pt.ToString() + " masked", masked); * } */ } } } wait: int c = Cv2.WaitKey(0); if (c == 'n' && index < files.Count - 1) { index++; } else if (c == 'p' && index > 0) { index--; } else if (c == 27) { break; } else { index = 0; } Window.DestroyAllWindows(); } } } } catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); } } }
static int VoteForSizeAndOrientation(KeyPoint[] modelKeyPoints, KeyPoint[] observedKeyPoints, DMatch[][] matches, Mat mask, float scaleIncrement, int rotationBins) { int idx = 0; int nonZeroCount = 0; byte[] maskMat = new byte[mask.Rows]; GCHandle maskHandle = GCHandle.Alloc(maskMat, GCHandleType.Pinned); using (Mat m = new Mat(mask.Rows, 1, MatType.CV_8U, maskHandle.AddrOfPinnedObject())) { mask.CopyTo(m); List <float> logScale = new List <float>(); List <float> rotations = new List <float>(); double s, maxS, minS, r; maxS = -1.0e-10f; minS = 1.0e10f; //if you get an exception here, it's because you're passing in the model and observed keypoints backwards. Just switch the order. for (int i = 0; i < maskMat.Length; i++) { if (maskMat[i] > 0) { KeyPoint observedKeyPoint = observedKeyPoints[i]; KeyPoint modelKeyPoint = modelKeyPoints[matches[i][0].TrainIdx]; s = Math.Log10(observedKeyPoint.Size / modelKeyPoint.Size); logScale.Add((float)s); maxS = s > maxS ? s : maxS; minS = s < minS ? s : minS; r = observedKeyPoint.Angle - modelKeyPoint.Angle; r = r < 0.0f ? r + 360.0f : r; rotations.Add((float)r); } } int scaleBinSize = (int)Math.Ceiling((maxS - minS) / Math.Log10(scaleIncrement)); if (scaleBinSize < 2) { scaleBinSize = 2; } float[] scaleRanges = { (float)minS, (float)(minS + scaleBinSize + Math.Log10(scaleIncrement)) }; using (MatOfFloat scalesMat = new MatOfFloat(rows: logScale.Count, cols: 1, data: logScale.ToArray())) using (MatOfFloat rotationsMat = new MatOfFloat(rows: rotations.Count, cols: 1, data: rotations.ToArray())) using (MatOfFloat flagsMat = new MatOfFloat(logScale.Count, 1)) using (Mat hist = new Mat()) { flagsMat.SetTo(new Scalar(0.0f)); float[] flagsMatFloat1 = flagsMat.ToArray(); int[] histSize = { scaleBinSize, rotationBins }; float[] rotationRanges = { 0.0f, 360.0f }; int[] channels = { 0, 1 }; Rangef[] ranges = { new Rangef(scaleRanges[0], scaleRanges[1]), new Rangef(0.0f, 360.0f) }; double minVal, maxVal; Mat[] arrs = { scalesMat, rotationsMat }; Cv2.CalcHist(arrs, channels, null, hist, 2, histSize, ranges); Cv2.MinMaxLoc(hist, out minVal, out maxVal); Cv2.Threshold(hist, hist, maxVal * 0.5, 0, ThresholdTypes.Tozero); Cv2.CalcBackProject(arrs, channels, hist, flagsMat, ranges); MatIndexer <float> flagsMatIndexer = flagsMat.GetIndexer(); for (int i = 0; i < maskMat.Length; i++) { if (maskMat[i] > 0) { if (flagsMatIndexer[idx++] != 0.0f) { nonZeroCount++; } else { maskMat[i] = 0; } } } m.CopyTo(mask); } } maskHandle.Free(); return(nonZeroCount); }
static int VoteForSizeAndOrientation(KeyPoint[] modelKeyPoints, KeyPoint[] observedKeyPoints, DMatch[][] matches, Mat mask, float scaleIncrement, int rotationBins) { int idx = 0; int nonZeroCount = 0; byte[] maskMat = new byte[mask.Rows]; GCHandle maskHandle = GCHandle.Alloc(maskMat, GCHandleType.Pinned); using (Mat m = new Mat(mask.Rows, 1, MatType.CV_8U, maskHandle.AddrOfPinnedObject())) { mask.CopyTo(m); List<float> logScale = new List<float>(); List<float> rotations = new List<float>(); double s, maxS, minS, r; maxS = -1.0e-10f; minS = 1.0e10f; //if you get an exception here, it's because you're passing in the model and observed keypoints backwards. Just switch the order. for (int i = 0; i < maskMat.Length; i++) { if (maskMat[i] > 0) { KeyPoint observedKeyPoint = observedKeyPoints[i]; KeyPoint modelKeyPoint = modelKeyPoints[matches[i][0].TrainIdx]; s = Math.Log10(observedKeyPoint.Size / modelKeyPoint.Size); logScale.Add((float)s); maxS = s > maxS ? s : maxS; minS = s < minS ? s : minS; r = observedKeyPoint.Angle - modelKeyPoint.Angle; r = r < 0.0f ? r + 360.0f : r; rotations.Add((float)r); } } int scaleBinSize = (int)Math.Ceiling((maxS - minS) / Math.Log10(scaleIncrement)); if (scaleBinSize < 2) scaleBinSize = 2; float[] scaleRanges = { (float)minS, (float)(minS + scaleBinSize + Math.Log10(scaleIncrement)) }; using (MatOfFloat scalesMat = new MatOfFloat(rows: logScale.Count, cols: 1, data: logScale.ToArray())) using (MatOfFloat rotationsMat = new MatOfFloat(rows: rotations.Count, cols: 1, data: rotations.ToArray())) using (MatOfFloat flagsMat = new MatOfFloat(logScale.Count, 1)) using (Mat hist = new Mat()) { flagsMat.SetTo(new Scalar(0.0f)); float[] flagsMatFloat1 = flagsMat.ToArray(); int[] histSize = { scaleBinSize, rotationBins }; float[] rotationRanges = { 0.0f, 360.0f }; int[] channels = { 0, 1 }; Rangef[] ranges = { new Rangef(scaleRanges[0], scaleRanges[1]), new Rangef(rotations.Min(), rotations.Max()) }; double minVal, maxVal; Mat[] arrs = { scalesMat, rotationsMat }; Cv2.CalcHist(arrs, channels, null, hist, 2, histSize, ranges); Cv2.MinMaxLoc(hist, out minVal, out maxVal); Cv2.Threshold(hist, hist, maxVal * 0.5, 0, ThresholdTypes.Tozero); Cv2.CalcBackProject(arrs, channels, hist, flagsMat, ranges); MatIndexer<float> flagsMatIndexer = flagsMat.GetIndexer(); for (int i = 0; i < maskMat.Length; i++) { if (maskMat[i] > 0) { if (flagsMatIndexer[idx++] != 0.0f) { nonZeroCount++; } else maskMat[i] = 0; } } m.CopyTo(mask); } } maskHandle.Free(); return nonZeroCount; }
static void GenSIFT(string path, string filename) { try { using (Mat input = new Mat(path, LoadMode.GrayScale)){ if (input.Empty()) { return; } double h = input.Rows, w = input.Cols; double newh, neww; if (h > w) { newh = maxSize; neww = Math.Ceiling(w / h * maxSize); } else { neww = maxSize; newh = Math.Ceiling(h / w * maxSize); } Size newsize = new Size(neww, newh); using (Mat rinput = new Mat()) { Cv2.Resize(input, rinput, newsize); /* using (new Window("image", rinput)) * { * Cv2.WaitKey(); * }*/ using (MatOfFloat descriptors = new MatOfFloat()) { sift.Run(rinput, null, out keypoint, descriptors); cnt += 1; Console.Out.WriteLine(descriptors.Rows + " " + cnt); var indexer = descriptors.GetIndexer(); UInt64 v = 0; for (int i = 0; i < 16; i++) { v *= 16; if (filename[i] >= '0' && filename[i] <= '9') { v += (UInt64)filename[i] - '0'; } else { v += (UInt64)(filename[i] - 'a') + 10; } } for (int i = 0; i < descriptors.Rows; i++) { bw.Write((UInt64)v); for (int j = 0; j < descriptors.Cols; j++) { Byte b = (Byte)indexer[i, j]; bw.Write(b); } } tot += descriptors.Rows; input.Release(); rinput.Release(); descriptors.Release(); } } } } catch { return; } }
public override object Find() { initialize(); CircleSegment[] circles = null; Point[][] points = Cv2.FindContoursAsArray(gray, RetrievalModes.List, ContourApproximationModes.ApproxTC89L1); for (int i = 0; i < points.Length; i++) { Mat black = new Mat(gray.Rows, gray.Cols, gray.Type(), new Scalar(0)); Cv2.DrawContours(black, points, i, new Scalar(255), Cv2.FILLED); Cv2.ImShow("contour", black); //for more info https://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=houghcircles circles = Cv2.HoughCircles(black, HoughMethods.Gradient, dp, minDist, cannyThreshold, param2, minRadius, maxRadius); // draw the circle detected foreach (CircleSegment element in circles) { Point center = new Point(Math.Round(element.Center.X), Math.Round(element.Center.Y)); Cv2.Circle(outputimg, center, 3, new Scalar(0, 255, 255), 1); Cv2.Circle(outputimg, center, (int)element.Radius, new Scalar(0, 0, 255), 1); } //compute distance transorm Mat dt = new Mat(); Cv2.Canny(black, canny, cannyThreshold, cannyThreshold / 2); Mat wh = new Mat(canny.Rows, canny.Cols, MatType.CV_8UC1, new Scalar(255)); Cv2.DistanceTransform(wh - canny.GreaterThan(0.0), dt, DistanceTypes.L2, DistanceMaskSize.Mask3); //Cv2.ImShow("dt", wh - canny.GreaterThan(0.0)); //Cv2.WaitKey(0); //test for semi-circle foreach (CircleSegment element in circles) { //test inlier percentage //sample the circle and check for distance to next edge uint counter = 0; uint inlier = 0; //maximal distance of inlier might depend on the size of the circle //the more close edge the lower distance transform value double maxInlierDist = element.Radius / maxInlierDistRatio; if (maxInlierDist < minInlierDist) { maxInlierDist = minInlierDist; } MatOfFloat mf = new MatOfFloat(dt); var indexer = mf.GetIndexer(); //TODO maybe parameter incrementation might depend on circle size for (float t = 0; t < 2 * Math.PI; t += 0.1f) { counter++; int cx = (int)(element.Radius * Math.Cos(t) + element.Center.X); int cy = (int)(element.Radius * Math.Sin(t) + element.Center.Y); if (cx < 0 || cy < 0 || cx > dt.Cols || cy >= dt.Rows) { continue; } if (indexer[cy, cx] < maxInlierDist) //carefor the image coordinate { inlier++; Cv2.Circle(outputimg, cx, cy, 3, new Scalar(255, 255, 255)); } else { Cv2.Circle(outputimg, cx, cy, 3, new Scalar(255, 0, 0)); } } Console.WriteLine("{0}% of a circle with radius {1} detected", 100 * inlier / counter, element.Radius); } } return(circles); }