이미지 유사도 프로그램을 위해서는 먼저 C#의 OpenCVSharp4를 Nuget package 관리자를 통해 설치 후 프로그램을 작성한다. 하기의 코드는 두장의 이미지를 활용하여 이미지가 얼마나 유사한지를 결과로 보여주는 예제이다.
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.XFeatures2D;
namespace Feature_Matching
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// 비교 이미지 입력1
var img1 = new Mat(@"1.bmp", ImreadModes.Grayscale);
Cv2.WaitKey(1); // do events
Mat Mat_dst = img1.SubMat(new Rect(700, 600, 900, 1000));// 전체이미지에서 비교할 부분이미지를 사각형으로 추출한다.
// 비교 이미지 입력2
var img2 = new Mat(@"2.bmp", ImreadModes.Grayscale);
Cv2.WaitKey(1); // do events
Mat Mat_dst2 = img2.SubMat(new Rect(700, 600, 900, 1000));// 전체이미지에서 비교할 부분이미지를 사각형으로 추출한다.
// 키포인트 검출
// FastFeatureDetector, StarDetector, SIFT, SURF, ORB, BRISK, MSER, GFTTDetector, DenseFeatureDetector, SimpleBlobDetector
// SURF = Speeded Up Robust Features
var Detector = SURF.Create(hessianThreshold: 400); //A good default value could be from 300 to 500, depending from the image contrast.
var keypoints1 = Detector.Detect(Mat_dst);
var keypoints2 = Detector.Detect(Mat_dst2);
// descriptors 계산, BRIEF, FREAK
// BRIEF = Binary Robust Independent Elementary Features
var extractor = BriefDescriptorExtractor.Create();
var Descriptors1 = new Mat();
var Descriptors2 = new Mat();
extractor.Compute(Mat_dst, ref keypoints1, Descriptors1);
extractor.Compute(Mat_dst2, ref keypoints2, Descriptors2);
// matching descriptors
var matcher = new BFMatcher();
var matches = matcher.Match(Descriptors1, Descriptors2);
// drawing the results
var imgMatches = new Mat();
Cv2.DrawMatches(Mat_dst, keypoints1, Mat_dst2, keypoints2, matches, imgMatches);
Cv2.ImShow("Matches", imgMatches);
double number_keypoints = 0;
double number_keypoints2 = 0;
if (keypoints1.Length <= keypoints2.Length)
{
number_keypoints = keypoints1.Length;
number_keypoints2 = keypoints2.Length;
}
else
{
number_keypoints = keypoints2.Length;
number_keypoints2 = keypoints1.Length;
}
Console.WriteLine("Keypoints 1ST Image: " + keypoints1.Length);
Console.WriteLine("Keypoints 2ND Image: " + keypoints2.Length);
Console.WriteLine("Score: " + (double)number_keypoints / number_keypoints2);
Cv2.WaitKey(1); // do events
Cv2.WaitKey(0);
Cv2.DestroyAllWindows();
Mat_dst.Dispose();
Mat_dst2.Dispose();
}
}
}
1. 서로 다른 이미지 비교
비교 이미지 1
비교 이미지2
결과
Keypoints 1ST Image: 996
Keypoints 2ND Image: 1425
Score: 0.698947368421053
2. 서로 같은 이미지 비교
비교 이미지 1
비교 이미지2
결과
Keypoints 1ST Image: 996
Keypoints 2ND Image: 996
Score: 1
결론
스코어 최대 0~1까지의 결과를 출력하는 상기의 프로그램에서 서로 다른 이미지를 비교할 경우 결과는 약 0.698947368421053 정도 이며 같은 이미지를 사용할 경우는 최대 1이라는 결과를 출력 했다. 위 알고리즘은 회전된 이미지에 대해서도 특징을 찾아서 결과를 출력해준다.
댓글