C\#에서 OpenCvsharp 가 특징 점 을 통 해 그림 과 일치 하 는 방법
8494 단어 OpenCvSharp특징.매 칭그림.
이 보조 자 체 는 어렵 지 않 습 니 다.바로 끊 임 없 는 캡 처 를 통 해 이 캡 처 에서 해당 동작 을 나타 내 는 버튼 이나 트리거 조건 을 나타 내 는 작은 그림 을 찾 는 것 입 니 다.
찾 으 면 이 하위 영역의 왼쪽 상단 좌 표를 가 져 오고 windows API 를 통 해 마우스 나 키 보드 를 호출 하여 조작 하면 됩 니 다.
이 중에서 가장 어 려 운 것 은 바로 그림 을 찾 는 것 이다.그림 을 정확하게 찾 아야 하고 서로 다른 해상도 에서 그림 을 찾 는 것 이 가장 좋 기 때문에 템 플 릿 이 일치 하 는 토대 에서 SIFT 와 SURF 의 특징 점 에서 그림 을 찾 는 방식 이 있다.
쓰 는 과정 에서 자 료 를 찾 았 는데 대부분이 C++또는 python 이 었 고 원생 의 C\#가 실현 되 지 않 았 기 때문에 저 는 직접 번역 을 가 져 왔 습 니 다(약간 변경).
SIFT 알고리즘
public static Bitmap MatchPicBySift(Bitmap imgSrc, Bitmap imgSub)
{
using (Mat matSrc = imgSrc.ToMat())
using (Mat matTo = imgSub.ToMat())
using (Mat matSrcRet = new Mat())
using (Mat matToRet = new Mat())
{
KeyPoint[] keyPointsSrc, keyPointsTo;
using (var sift = OpenCvSharp.XFeatures2D.SIFT.Create())
{
sift.DetectAndCompute(matSrc, null, out keyPointsSrc, matSrcRet);
sift.DetectAndCompute(matTo, null, out keyPointsTo, matToRet);
}
using (var bfMatcher = new OpenCvSharp.BFMatcher())
{
var matches = bfMatcher.KnnMatch(matSrcRet, matToRet, k: 2);
var pointsSrc = new List<Point2f>();
var pointsDst = new List<Point2f>();
var goodMatches = new List<DMatch>();
foreach (DMatch[] items in matches.Where(x => x.Length > 1))
{
if (items[0].Distance < 0.5 * items[1].Distance)
{
pointsSrc.Add(keyPointsSrc[items[0].QueryIdx].Pt);
pointsDst.Add(keyPointsTo[items[0].TrainIdx].Pt);
goodMatches.Add(items[0]);
Console.WriteLine($"{keyPointsSrc[items[0].QueryIdx].Pt.X}, {keyPointsSrc[items[0].QueryIdx].Pt.Y}");
}
}
var outMat = new Mat();
// RANSAC
var pSrc = pointsSrc.ConvertAll(Point2fToPoint2d);
var pDst = pointsDst.ConvertAll(Point2fToPoint2d);
var outMask = new Mat();
// ,
if (pSrc.Count > 0 && pDst.Count > 0)
Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac, mask: outMask);
// RANSAC 10 , . ( RANSAC , 0 ).
if (outMask.Rows > 10)
{
byte[] maskBytes = new byte[outMask.Rows * outMask.Cols];
outMask.GetArray(0, 0, maskBytes);
Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, matchesMask: maskBytes, flags: DrawMatchesFlags.NotDrawSinglePoints);
}
else
Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, flags: DrawMatchesFlags.NotDrawSinglePoints);
return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
}
}
}
SURF 알고리즘
public static Bitmap MatchPicBySurf(Bitmap imgSrc, Bitmap imgSub, double threshold = 400)
{
using (Mat matSrc = imgSrc.ToMat())
using (Mat matTo = imgSub.ToMat())
using (Mat matSrcRet = new Mat())
using (Mat matToRet = new Mat())
{
KeyPoint[] keyPointsSrc, keyPointsTo;
using (var surf = OpenCvSharp.XFeatures2D.SURF.Create(threshold,4,3,true,true))
{
surf.DetectAndCompute(matSrc, null, out keyPointsSrc, matSrcRet);
surf.DetectAndCompute(matTo, null, out keyPointsTo, matToRet);
}
using (var flnMatcher = new OpenCvSharp.FlannBasedMatcher())
{
var matches = flnMatcher.Match(matSrcRet, matToRet);
//
double minDistance = 1000;//
double maxDistance = 0;
for (int i = 0; i < matSrcRet.Rows; i++)
{
double distance = matches[i].Distance;
if (distance > maxDistance)
{
maxDistance = distance;
}
if (distance < minDistance)
{
minDistance = distance;
}
}
Console.WriteLine($"max distance : {maxDistance}");
Console.WriteLine($"min distance : {minDistance}");
var pointsSrc = new List<Point2f>();
var pointsDst = new List<Point2f>();
//
var goodMatches = new List<DMatch>();
for (int i = 0; i < matSrcRet.Rows; i++)
{
double distance = matches[i].Distance;
if (distance < Math.Max(minDistance * 2, 0.02))
{
pointsSrc.Add(keyPointsSrc[matches[i].QueryIdx].Pt);
pointsDst.Add(keyPointsTo[matches[i].TrainIdx].Pt);
// DMatch
goodMatches.Add(matches[i]);
}
}
var outMat = new Mat();
// RANSAC
var pSrc = pointsSrc.ConvertAll(Point2fToPoint2d);
var pDst = pointsDst.ConvertAll(Point2fToPoint2d);
var outMask = new Mat();
// ,
if (pSrc.Count > 0 && pDst.Count > 0)
Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac, mask: outMask);
// RANSAC 10 , . ( RANSAC , 0 ).
if (outMask.Rows > 10)
{
byte[] maskBytes = new byte[outMask.Rows * outMask.Cols];
outMask.GetArray(0, 0, maskBytes);
Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, matchesMask: maskBytes, flags: DrawMatchesFlags.NotDrawSinglePoints);
}
else
Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, flags: DrawMatchesFlags.NotDrawSinglePoints);
return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
}
}
}
템 플 릿 일치
public static System.Drawing.Point FindPicFromImage(Bitmap imgSrc, Bitmap imgSub, double threshold = 0.9)
{
OpenCvSharp.Mat srcMat = null;
OpenCvSharp.Mat dstMat = null;
OpenCvSharp.OutputArray outArray = null;
try
{
srcMat = imgSrc.ToMat();
dstMat = imgSub.ToMat();
outArray = OpenCvSharp.OutputArray.Create(srcMat);
OpenCvSharp.Cv2.MatchTemplate(srcMat, dstMat, outArray, Common.templateMatchModes);
double minValue, maxValue;
OpenCvSharp.Point location, point;
OpenCvSharp.Cv2.MinMaxLoc(OpenCvSharp.InputArray.Create(outArray.GetMat()), out minValue, out maxValue, out location, out point);
Console.WriteLine(maxValue);
if (maxValue >= threshold)
return new System.Drawing.Point(point.X, point.Y);
return System.Drawing.Point.Empty;
}
catch(Exception ex)
{
return System.Drawing.Point.Empty;
}
finally
{
if (srcMat != null)
srcMat.Dispose();
if (dstMat != null)
dstMat.Dispose();
if (outArray != null)
outArray.Dispose();
}
}
총결산
위 에서 말씀 드 린 것 은 편집장 님 께 서 소개 해 주신 C\#중 OpenCvsharp 이 특징 점 을 통 해 그림 과 일치 하 는 것 입 니 다.여러분 께 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
만약 당신 이 본문 이 당신 에 게 도움 이 된다 고 생각한다 면,전 재 를 환영 합 니 다.번 거 로 우 시 겠 지만 출처 를 밝 혀 주 십시오.감사합니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Rx 및 OpenCVSharp를 사용하여 쉽게 카메라 캡처 앱 만들기최근 몇년은 프로젝트에 틈이 없고(게다가 타이트 스케줄) 자신의 자기 단련이 완만하게 되어 있었습니다만, 굉장히 사내 니트가 되었습니다 이것을 기회에 다양한 것에 도전해 업할까라고 생각하고 있습니다. 자신의 경험 분...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.