public Image <Bgr, byte> pointComp(Image <Bgr, byte> baseImg, Image <Bgr, byte> twistedImg) { Image <Gray, byte> baseImgGray = baseImg.Convert <Gray, byte>(); Image <Gray, byte> twistedImgGray = twistedImg.Convert <Gray, byte>(); Brisk descriptor = new Brisk(); GFTTDetector detector = new GFTTDetector(40, 0.01, 5, 3, true); VectorOfKeyPoint GFP1 = new VectorOfKeyPoint(); UMat baseDesc = new UMat(); UMat bimg = twistedImgGray.Mat.GetUMat(AccessType.Read); VectorOfKeyPoint GFP2 = new VectorOfKeyPoint(); UMat twistedDesc = new UMat(); UMat timg = baseImgGray.Mat.GetUMat(AccessType.Read); detector.DetectRaw(bimg, GFP1); descriptor.Compute(bimg, GFP1, baseDesc); detector.DetectRaw(timg, GFP2); descriptor.Compute(timg, GFP2, twistedDesc); BFMatcher matcher = new BFMatcher(DistanceType.L2); VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch(); matcher.Add(baseDesc); matcher.KnnMatch(twistedDesc, matches, 2, null); Mat mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1); mask.SetTo(new MCvScalar(255)); Features2DToolbox.VoteForUniqueness(matches, 0.8, mask); //int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(GFP1, GFP1, matches, mask, 1.5, 20); Image <Bgr, byte> res = baseImg.CopyBlank(); Features2DToolbox.DrawMatches(twistedImg, GFP1, baseImg, GFP2, matches, res, new MCvScalar(255, 0, 0), new MCvScalar(255, 0, 0), mask); return(res); }
private void button3_Click(object sender, EventArgs e) { GFTTDetector detector = new GFTTDetector(40, 0.01, 5, 3, true); var baseImgGray = baseImg.Convert <Gray, byte>(); var twistedImgGray = twistedImg.Convert <Gray, byte>(); //генератор описания ключевых точек Brisk descriptor = new Brisk(); //поскольку в данном случае необходимо посчитать обратное преобразование //базой будет являться изменённое изображение VectorOfKeyPoint GFP1 = new VectorOfKeyPoint(); UMat baseDesc = new UMat(); UMat bimg = twistedImgGray.Mat.GetUMat(AccessType.Read); VectorOfKeyPoint GFP2 = new VectorOfKeyPoint(); UMat twistedDesc = new UMat(); UMat timg = baseImgGray.Mat.GetUMat(AccessType.Read); //получение необработанной информации о характерных точках изображений detector.DetectRaw(bimg, GFP1); //генерация описания характерных точек изображений descriptor.Compute(bimg, GFP1, baseDesc); detector.DetectRaw(timg, GFP2); descriptor.Compute(timg, GFP2, twistedDesc); //класс позволяющий сравнивать описания наборов ключевых точек BFMatcher matcher = new BFMatcher(DistanceType.L2); //массив для хранения совпадений характерных точек VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch(); //добавление описания базовых точек matcher.Add(baseDesc); //сравнение с описанием изменённых matcher.KnnMatch(twistedDesc, matches, 2, null); //3й параметр - количество ближайших соседей среди которых осуществляется поиск совпадений //4й параметр - маска, в данном случае не нужна //маска для определения отбрасываемых значений (аномальных и не уникальных) Mat mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1); mask.SetTo(new MCvScalar(255)); //определение уникальных совпадений Features2DToolbox.VoteForUniqueness(matches, 0.8, mask); Mat homography; //получение матрицы гомографии homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(GFP1, GFP2, matches, mask, 2); var destImage = new Image <Bgr, byte>(baseImg.Size); CvInvoke.WarpPerspective(twistedImg, destImage, homography, destImage.Size); twistedImg = destImage; imageBox2.Image = destImage.Resize(640, 480, Inter.Linear); }
public Image <Bgr, byte> ReturnCompared(out Image <Bgr, byte> def, out Image <Bgr, byte> twistdef) { var image = sourceImage.Copy(); var twistedImg = additionalImage.Copy(); //генератор описания ключевых точек Brisk descriptor = new Brisk(); GFTTDetector detector = new GFTTDetector(40, 0.01, 5, 3, true); //поскольку в данном случае необходимо посчитать обратное преобразование //базой будет являться изменённое изображение VectorOfKeyPoint GFP1 = new VectorOfKeyPoint(); UMat baseDesc = new UMat(); var twistedImgGray = twistedImg.Convert <Gray, byte>(); var baseImgGray = image.Convert <Gray, byte>(); UMat bimg = twistedImgGray.Mat.GetUMat(AccessType.Read); VectorOfKeyPoint GFP2 = new VectorOfKeyPoint(); UMat twistedDesc = new UMat(); UMat timg = baseImgGray.Mat.GetUMat(AccessType.Read); //получение необработанной информации о характерных точках изображений detector.DetectRaw(bimg, GFP1); //генерация описания характерных точек изображений descriptor.Compute(bimg, GFP1, baseDesc); detector.DetectRaw(timg, GFP2); descriptor.Compute(timg, GFP2, twistedDesc); BFMatcher matcher = new BFMatcher(DistanceType.L2); //массив для хранения совпадений характерных точек VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch(); //добавление описания базовых точек matcher.Add(baseDesc); //сравнение с описанием изменённых matcher.KnnMatch(twistedDesc, matches, 2, null); Mat mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1); mask.SetTo(new MCvScalar(255)); //определение уникальных совпадений Mat resM = new Mat(image.Height, image.Width * 2, DepthType.Cv8U, 3); var res = resM.ToImage <Bgr, byte>(); Features2DToolbox.VoteForUniqueness(matches, 0.8, mask); int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(GFP1, GFP1, matches, mask, 1.5, 20); Features2DToolbox.DrawMatches(twistedImg, GFP1, image, GFP2, matches, res, new MCvScalar(255, 0, 0), new MCvScalar(255, 0, 0), mask); def = image; twistdef = twistedImg; return(res); }
private void button_Detect_Click(object sender, EventArgs e) { Mat scr = imagemat; Mat result = imagemat.Clone(); #region Detect()代码 /* * GFTTDetector _gftd = new GFTTDetector();//以默认参数创建 GFTTDetector 类。 * MKeyPoint[] keypoints = _gftd.Detect(scr, null);//检测关键点,返回 MKeyPoint[]。 * foreach (MKeyPoint keypoint in keypoints)//遍历 MKeyPoint[]数组。 * { * Point point = Point.Truncate(keypoint.Point);//获得关键点的坐 标位置,以 Point 类型。 * CvInvoke.Circle(result, point, 3, new MCvScalar(0, 0, 255), 1);//绘 制关键点的位置,以 Circle 形式。 * } */ #endregion #region DetectRaw() code GFTTDetector _gftd = new GFTTDetector(); //以默认参数创建 GFTTDetector 类。 VectorOfKeyPoint vector_keypoints = new VectorOfKeyPoint(); //创建 VectorOfKeyPoint 类型,存储关键点集合。 _gftd.DetectRaw(scr, vector_keypoints, null); //检测关键点。 foreach (MKeyPoint keypoint in vector_keypoints.ToArray()) //遍历 MKeyPoint[]数组。 { Point point = Point.Truncate(keypoint.Point); //获得关键点的坐 标位置,以 Point 类型。 CvInvoke.Circle(result, point, 3, new MCvScalar(255, 255, 0), 1); //绘制关键点的位置,以 Circle 形式。 } #endregion imageBox1.Image = scr; //显示输入图像。 imageBox2.Image = result; //显示角点检测图像。 }
public Image <Bgr, byte> PointHomo(Image <Bgr, byte> image, Image <Bgr, byte> image2) { Image <Gray, byte> baseImgGray = image.Convert <Gray, byte>(); Image <Gray, byte> twistedImgGray = image2.Convert <Gray, byte>(); Brisk descriptor = new Brisk(); GFTTDetector detector = new GFTTDetector(40, 0.01, 5, 3, true); VectorOfKeyPoint GFP1 = new VectorOfKeyPoint(); UMat baseDesc = new UMat(); UMat bimg = twistedImgGray.Mat.GetUMat(AccessType.Read); VectorOfKeyPoint GFP2 = new VectorOfKeyPoint(); UMat twistedDesc = new UMat(); UMat timg = baseImgGray.Mat.GetUMat(AccessType.Read); detector.DetectRaw(bimg, GFP1); descriptor.Compute(bimg, GFP1, baseDesc); detector.DetectRaw(timg, GFP2); descriptor.Compute(timg, GFP2, twistedDesc); BFMatcher matcher = new BFMatcher(DistanceType.L2); VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch(); matcher.Add(baseDesc); matcher.KnnMatch(twistedDesc, matches, 2, null); Mat mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1); mask.SetTo(new MCvScalar(255)); Features2DToolbox.VoteForUniqueness(matches, 0.8, mask); int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(GFP1, GFP1, matches, mask, 1.5, 20); Image <Bgr, byte> res = image.CopyBlank(); Features2DToolbox.DrawMatches(image2, GFP1, image, GFP2, matches, res, new MCvScalar(255, 0, 0), new MCvScalar(255, 0, 0), mask); Mat homography; homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(GFP1, GFP2, matches, mask, 2); var destImage = new Image <Bgr, byte>(image2.Size); CvInvoke.WarpPerspective(image2, destImage, homography, destImage.Size); return(destImage); }
/// <summary> /// Find the 4 strongest corners using the GFTT algorithm. /// </summary> /// <param name="pieceID">ID of the piece</param> /// <param name="pieceImgBw">Black white image of piece</param> /// <param name="pieceImgColor">Color image of piece</param> /// <returns>List with corner points</returns> /// see: http://docs.opencv.org/doc/tutorials/features2d/trackingmotion/corner_subpixeles/corner_subpixeles.html public override List <Point> FindCorners(string pieceID, Bitmap pieceImgBw, Bitmap pieceImgColor) { PluginFactory.LogHandle.Report(new LogEventInfo(pieceID + " Finding corners with GFTT algorithm")); double minDistance = PluginFactory.GetGeneralSettingsPlugin().PuzzleMinPieceSize; //How close can 2 corners be? double min = 0; double max = 1; bool found_all_corners = false; Image <Gray, byte> bw_clone = new Image <Gray, byte>(pieceImgBw); List <Point> corners = new List <Point>(); //Binary search, altering quality until exactly 4 corners are found. Usually done in 1 or 2 iterations while (0 < MaxIterations--) { if (PluginFactory.CancelToken.IsCancellationRequested) { PluginFactory.CancelToken.ThrowIfCancellationRequested(); } double qualityLevel = (min + max) / 2; VectorOfKeyPoint keyPoints = new VectorOfKeyPoint(); GFTTDetector featureDetector = new GFTTDetector(100, qualityLevel, minDistance, BlockSize, true, HarrisDetectorParameterK); featureDetector.DetectRaw(bw_clone, keyPoints); if (keyPoints.Size > 4) { min = qualityLevel; //Found too many corners increase quality } else if (keyPoints.Size < 4) { max = qualityLevel; } else { for (int i = 0; i < keyPoints.Size; i++) { corners.Add(Point.Round(keyPoints[i].Point)); } found_all_corners = true; //found all corners break; } } //Find the sub-pixel locations of the corners. //Size winSize = new Size(blockSize, blockSize); //Size zeroZone = new Size(-1, -1); //MCvTermCriteria criteria = new MCvTermCriteria(40, 0.001); // Calculate the refined corner locations //CvInvoke.CornerSubPix(bw_clone, corners, winSize, zeroZone, criteria); if (PluginFactory.GetGeneralSettingsPlugin().SolverShowDebugResults) { Image <Rgb, byte> corner_img = new Image <Rgb, byte>(pieceImgColor); for (int i = 0; i < corners.Count; i++) { CvInvoke.Circle(corner_img, Point.Round(corners[i]), 7, new MCvScalar(255, 0, 0), -1); } PluginFactory.LogHandle.Report(new LogEventImage(pieceID + " Found Corners (" + corners.Count.ToString() + ")", corner_img.Bitmap)); corner_img.Dispose(); } if (!found_all_corners) { PluginFactory.LogHandle.Report(new LogEventError(pieceID + " Failed to find correct number of corners. " + corners.Count + " found.")); } return(corners); }