JAVA와 OpenCV를 이용하여 지난번에 추출한 SIFT Key Point를 가지고 빠른 매칭과 변환 행렬 추정을 진행하겠습니다.
빠른 매칭
public static void showLennaMatch() {
try {
String locGrayLennaOri = "경로생략/LennaGray.png";
String locGrayLennaTun = "경로생략/LennaGrayTurn.png";
Mat imageLennaOri = Imgcodecs.imread(locGrayLennaOri);
Mat imageLennaTun = Imgcodecs.imread(locGrayLennaTun);
MatOfKeyPoint keyPointOfLennaOri = new MatOfKeyPoint(), keyPointOfLennaTun = new MatOfKeyPoint();
SIFT.create().detect(imageLennaOri, keyPointOfLennaOri);
SIFT.create().detect(imageLennaTun, keyPointOfLennaTun);
Mat keyPointLennaOri = new Mat(), keyPointLennaTun = new Mat();
Features2d.drawKeypoints(imageLennaOri, keyPointOfLennaOri, keyPointLennaOri);
Features2d.drawKeypoints(imageLennaTun, keyPointOfLennaTun, keyPointLennaTun);
Mat descriptorsOri = new Mat(), descriptorsTun = new Mat();
SIFT.create().compute(imageLennaOri, keyPointOfLennaOri, descriptorsOri);
SIFT.create().compute(imageLennaTun, keyPointOfLennaTun, descriptorsTun);
// Match
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptorsOri, descriptorsTun, matches);
double maxd = 0.0; double mind = 100.0;
for (int index = 0; index < descriptorsOri.rows(); index++) {
double dist = matches.toArray()[index].distance;
if (dist<mind) mind=dist;
if (dist>maxd) maxd=dist;
}
List<DMatch> aryGoodMatches= new ArrayList<DMatch>();
MatOfDMatch goodMatches = new MatOfDMatch();
for (int index = 0; index < descriptorsOri.rows(); index++) {
if (matches.toArray()[index].distance <= Math.max(2*mind, 0.02)) aryGoodMatches.add(matches.toArray()[index]);
}
goodMatches.fromList(aryGoodMatches);
Mat imageLennaMatch = new Mat();
MatOfByte matchesMask = new MatOfByte();
Features2d.drawMatches(imageLennaOri, keyPointOfLennaOri, imageLennaTun, keyPointOfLennaTun,
goodMatches, imageLennaMatch, Scalar.all(-1), Scalar.all(-1), matchesMask, Features2d.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS);
// Show
HighGui.imshow("Match", imageLennaMatch);
HighGui.waitKey();
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
변환 행렬 추정
public static void showLennaTransform() {
try {
String locGrayLennaOri = "경로생략/LennaGray.png";
String locGrayLennaTun = "경로생략/LennaGrayTurn_1.png";
Mat imageLennaOri = Imgcodecs.imread(locGrayLennaOri);
Mat imageLennaTun = Imgcodecs.imread(locGrayLennaTun);
MatOfKeyPoint keyPointOfLennaOri = new MatOfKeyPoint(), keyPointOfLennaTun = new MatOfKeyPoint();
SIFT.create().detect(imageLennaOri, keyPointOfLennaOri);
SIFT.create().detect(imageLennaTun, keyPointOfLennaTun);
Mat keyPointLennaOri = new Mat(), keyPointLennaTun = new Mat();
Features2d.drawKeypoints(imageLennaOri, keyPointOfLennaOri, keyPointLennaOri);
Features2d.drawKeypoints(imageLennaTun, keyPointOfLennaTun, keyPointLennaTun);
Mat descriptorsOri = new Mat(), descriptorsTun = new Mat();
SIFT.create().compute(imageLennaOri, keyPointOfLennaOri, descriptorsOri);
SIFT.create().compute(imageLennaTun, keyPointOfLennaTun, descriptorsTun);
// Start Match
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptorsOri, descriptorsTun, matches);
double maxd = 0.0; double mind = 100.0;
for (int index = 0; index < descriptorsOri.rows(); index++) {
double dist = matches.toArray()[index].distance;
if (dist<mind) mind=dist;
if (dist>maxd) maxd=dist;
}
List<DMatch> aryGoodMatches = new ArrayList<DMatch>();
MatOfDMatch goodMatches = new MatOfDMatch();
for (int index = 0; index < descriptorsOri.rows(); index++) {
if (matches.toArray()[index].distance <= Math.max(2*mind, 0.02)) aryGoodMatches.add(matches.toArray()[index]);
}
goodMatches.fromList(aryGoodMatches);
Mat imageLennaMatch = new Mat();
MatOfByte matchesMask = new MatOfByte();
Features2d.drawMatches(imageLennaOri, keyPointOfLennaOri, imageLennaTun, keyPointOfLennaTun,
goodMatches, imageLennaMatch, Scalar.all(-1), Scalar.all(-1), matchesMask, Features2d.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS);
// End Match
// Start Transform
List<Point> aryModel_pt = new ArrayList<Point>(), aryScene_pt = new ArrayList<Point>();
MatOfPoint2f model_pt = new MatOfPoint2f(), scene_pt = new MatOfPoint2f();
for (int index = 0; index < aryGoodMatches.size(); index++) {
aryModel_pt.add(keyPointOfLennaOri.toArray()[aryGoodMatches.get(index).queryIdx].pt);
aryScene_pt.add(keyPointOfLennaTun.toArray()[aryGoodMatches.get(index).trainIdx].pt);
}
model_pt.fromList(aryModel_pt);
scene_pt.fromList(aryScene_pt);
Mat H = Calib3d.findHomography(model_pt, scene_pt, Calib3d.RANSAC);
MatOfPoint2f model_corner = new MatOfPoint2f();
List<Point> aryModel_corner = new ArrayList<Point>();
aryModel_corner.add(new Point(0, 0));
aryModel_corner.add(new Point(imageLennaTun.cols(), 0));
aryModel_corner.add(new Point(imageLennaTun.cols(), imageLennaTun.rows()));
aryModel_corner.add(new Point(0, imageLennaTun.rows()));
model_corner.fromList(aryModel_corner);
MatOfPoint2f scene_corner = new MatOfPoint2f();
Core.perspectiveTransform(model_corner, scene_corner, H);
Point p = new Point(imageLennaOri.cols(),0);
scene_corner.toArray()[0].x =+ p.x;
scene_corner.toArray()[0].y =+ p.y;
scene_corner.toArray()[1].x =+ p.x;
scene_corner.toArray()[1].y =+ p.y;
scene_corner.toArray()[2].x =+ p.x;
scene_corner.toArray()[2].y =+ p.y;
scene_corner.toArray()[3].x =+ p.x;
scene_corner.toArray()[3].y =+ p.y;
Imgproc.line(imageLennaMatch, scene_corner.toArray()[0], scene_corner.toArray()[1], new Scalar(0, 0, 255), 3);
Imgproc.line(imageLennaMatch, scene_corner.toArray()[1], scene_corner.toArray()[2], new Scalar(0, 0, 255), 3);
Imgproc.line(imageLennaMatch, scene_corner.toArray()[2], scene_corner.toArray()[3], new Scalar(0, 0, 255), 3);
Imgproc.line(imageLennaMatch, scene_corner.toArray()[3], scene_corner.toArray()[0], new Scalar(0, 0, 255), 3);
// End Transform
// Show
HighGui.imshow("Transform", imageLennaMatch);
HighGui.waitKey();
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
'프로그래밍 > OpenCV.' 카테고리의 다른 글
[OpenCV] 06.. SIFT Key Point, 기술자 추출(feat.JAVA) (0) | 2020.11.02 |
---|---|
[OpenCV] 05.. Canny Edge와 Sobel Edge(feat.JAVA) (2) | 2020.11.02 |
[OpenCV] 04.. OpenCV 평활화와 이진화(feat.JAVA) (0) | 2020.10.17 |
[OpenCV] 03.. OpenCV 히스토그램(feat.JAVA) (0) | 2020.10.17 |
[OpenCV] 02.. Gray Scale과 Resize (2) | 2020.09.20 |
댓글