android 字符串相似度对比,Android中的OpenCV图像比较和相似度

Andrii Omelc..

7

但是我们可以看到两个图像都具有相同的视觉元素(in).

因此,我们应该比较不是整个图像,而是"相同的视觉元素".Match如果不比较"模板"和"相机"图像本身,您可以更多地提高价值,但处理方式相同(例如转换为二进制黑/白)"模板"和"相机"图像.例如,尝试在两个("模板"和"相机")图像上找到蓝色(模板徽标的背景)正方形,并比较该正方形(感兴趣的区域).代码可能是这样的:

Bitmap bmImageTemplate = ;

Bitmap bmTemplate = findLogo(bmImageTemplate); // process template image

Bitmap bmImage = ;

Bitmap bmLogo = findLogo(bmImage); // process camera image same way

compareBitmaps(bmTemplate, bmLogo);

哪里

private Bitmap findLogo(Bitmap sourceBitmap) {

Bitmap roiBitmap = null;

Mat sourceMat = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);

Utils.bitmapToMat(sourceBitmap, sourceMat);

Mat roiTmp = sourceMat.clone();

final Mat hsvMat = new Mat();

sourceMat.copyTo(hsvMat);

// convert mat to HSV format for Core.inRange()

Imgproc.cvtColor(hsvMat, hsvMat, Imgproc.COLOR_RGB2HSV);

Scalar lowerb = new Scalar(85, 50, 40); // lower color border for BLUE

Scalar upperb = new Scalar(135, 255, 255); // upper color border for BLUE

Core.inRange(hsvMat, lowerb, upperb, roiTmp); // select only blue pixels

// find contours

List contours = new ArrayList<>();

List squares = new ArrayList<>();

Imgproc.findContours(roiTmp, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

// find appropriate bounding rectangles

for (MatOfPoint contour : contours) {

MatOfPoint2f areaPoints = new MatOfPoint2f(contour.toArray());

RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints);

double rectangleArea = boundingRect.size.area();

// test min ROI area in pixels

if (rectangleArea > 400) {

Point rotated_rect_points[] = new Point[4];

boundingRect.points(rotated_rect_points);

Rect rect = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points));

double aspectRatio = rect.width > rect.height ?

(double) rect.height / (double) rect.width : (double) rect.width / (double) rect.height;

if (aspectRatio >= 0.9) {

squares.add(rect);

}

}

}

Mat logoMat = extractSquareMat(roiTmp, getBiggestSquare(squares));

roiBitmap = Bitmap.createBitmap(logoMat.cols(), logoMat.rows(), Bitmap.Config.ARGB_8888);

Utils.matToBitmap(logoMat, roiBitmap);

return roiBitmap;

}

方法extractSquareMat()只从整个图像中提取感兴趣区域(徽标)

public static Mat extractSquareMat(Mat sourceMat, Rect rect) {

Mat squareMat = null;

int padding = 50;

if (rect != null) {

Rect truncatedRect = new Rect((int) rect.tl().x + padding, (int) rect.tl().y + padding,

rect.width - 2 * padding, rect.height - 2 * padding);

squareMat = new Mat(sourceMat, truncatedRect);

}

return squareMat ;

}

并compareBitmaps()为您的代码包装:

private void compareBitmaps(Bitmap bitmap1, Bitmap bitmap2) {

Mat mat1 = new Mat(bitmap1.getWidth(), bitmap1.getHeight(), CvType.CV_8UC3);

Utils.bitmapToMat(bitmap1, mat1);

Mat mat2 = new Mat(bitmap2.getWidth(), bitmap2.getHeight(), CvType.CV_8UC3);

Utils.bitmapToMat(bitmap2, mat2);

compareMats(mat1, mat2);

}

你的代码作为方法:

private void compareMats(Mat img1, Mat img2) {

FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);

DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.BRIEF);

DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);

Mat descriptors1 = new Mat();

MatOfKeyPoint keypoints1 = new MatOfKeyPoint();

detector.detect(img1, keypoints1);

extractor.compute(img1, keypoints1, descriptors1);

//second image

// Mat img2 = Imgcodecs.imread(path2);

Mat descriptors2 = new Mat();

MatOfKeyPoint keypoints2 = new MatOfKeyPoint();

detector.detect(img2, keypoints2);

extractor.compute(img2, keypoints2, descriptors2);

//matcher image descriptors

MatOfDMatch matches = new MatOfDMatch();

matcher.match(descriptors1,descriptors2,matches);

// Filter matches by distance

MatOfDMatch filtered = filterMatchesByDistance(matches);

int total = (int) matches.size().height;

int Match= (int) filtered.size().height;

Log.d("LOG", "total:" + total + " Match:" + Match);

}

static MatOfDMatch filterMatchesByDistance(MatOfDMatch matches){

List matches_original = matches.toList();

List matches_filtered = new ArrayList();

int DIST_LIMIT = 30;

// Check all the matches distance and if it passes add to list of filtered matches

Log.d("DISTFILTER", "ORG SIZE:" + matches_original.size() + "");

for (int i = 0; i < matches_original.size(); i++) {

DMatch d = matches_original.get(i);

if (Math.abs(d.distance) <= DIST_LIMIT) {

matches_filtered.add(d);

}

}

Log.d("DISTFILTER", "FIL SIZE:" + matches_filtered.size() + "");

MatOfDMatch mat = new MatOfDMatch();

mat.fromList(matches_filtered);

return mat;

}

调整大小(缩放为50%)的结果是从您的问题结果中保存的图像是:

D/DISTFILTER: ORG SIZE:237

D/DISTFILTER: FIL SIZE:230

D/LOG: total:237 Match:230

NB!这是一个快速而肮脏的例子,仅用于演示给定模板的方法.

PS getBiggestSquare()可以是那样的(基于面积比较):

public static Rect getBiggestSquare(List squares) {

Rect biggestSquare = null;

if (squares != null && squares.size() >= 1) {

Rect square;

double maxArea;

int ixMaxArea = 0;

square = squares.get(ixMaxArea);

maxArea = square.area();

for (int ix = 1; ix < squares.size(); ix++) {

square = squares.get(ix);

if (square.area() > maxArea) {

maxArea = square.area();

ixMaxArea = ix;

}

}

biggestSquare = squares.get(ixMaxArea);

}

return biggestSquare;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值