无法将 matchTemplate Mat 结果转换为图像iOS、Objective-C

问题描述

我正在尝试查看函数 matchTemplate 的输出,如此处https://docs.opencv.org/3.4/de/da9/tutorial_template_matching.html

在我使用 matchTemplate 之后,我得到了结果 Mat 并且我能够调用 minMaxLoc 来获取某个位置,但是很难调试,因为我看不到灰色结果热图。

完整代码底部

首先,我将模板图像转换为不同的尺寸(稍微放大和缩小)和旋转。我将其设为灰度,并将基础图像设为灰度。

执行匹配后,我覆盖找到的矩形。这适用于某些部分,例如:

enter image description here

我将 BASE 图像从 Mat 转换为图像:

enter image description here

经过测试的从 Mat 到图像的 TEMPLATE 图像:

enter image description here

最后什么不起作用

图像的结果垫:

enter image description here

知道为什么这不能按照示例工作吗?根据代码,我使用 OpenCV 提供的 MatToUIImage 进行转换。

#import "TemplateMatch.h"
#include <vector>
#include <math.h>
#import "opencv2/imgcodecs/ios.h"

using namespace cv;
using namespace std;

@interface Templatematch() {
    UIImage *_templateImage;
    vector<Mat> _scaledTempls;
}

@end

@implementation TemplateMatch

static const float acceptableValue = 0.8;

- (void)setTemplateImage:(UIImage *)templateImage {
    _templateImage = templateImage;
    Mat templ = [self cvMatGrayFromUIImage:templateImage];
    _scaledTempls.clear();
    for(double i=0.9;i<1.1;i+=0.05) {
        Mat templResized;
        double z = MIN(i,1.0);
        resize(templ,templResized,cv::Size(0,0),z,z);
        _scaledTempls.push_back(templResized);
        Mat rotated;
        cv::rotate(templResized,rotated,ROTATE_90_Clockwise);
        _scaledTempls.push_back(rotated);
        cv::rotate(rotated,ROTATE_90_Clockwise);
        _scaledTempls.push_back(rotated);
    }
}

- (cv::Rect)matchWithMat:(Mat)img {
    double minVal;
    double maxVal;
    cv::Point minLoc;
    cv::Point maxLoc;

    for (int i=0; i < _scaledTempls.size(); i++) {
        Mat templ = _scaledTempls[i];
                
        Mat result;
        matchTemplate(img,templ,result,TM_CCOEFF_norMED);
        minMaxLoc(result,&minVal,&maxVal,&minLoc,&maxLoc,Mat());
        
        UIImage *base_image = MatToUIImage(img);
        [UIImageJPEGRepresentation(base_image,1.0) writetoFile:@"/Users/x/Desktop/outs/base_image.jpg" atomically:YES];
        UIImage *template_image = MatToUIImage(templ);
        Nsstring *templname = [Nsstring stringWithFormat:@"/Users/x/Desktop/outs/template_image_%i.jpg",i];
        [UIImageJPEGRepresentation(template_image,1.0) writetoFile:templname atomically:YES];
        UIImage *result_image = MatToUIImage(result);
        [UIImageJPEGRepresentation(result_image,1.0) writetoFile:@"/Users/x/Desktop/outs/result_image.jpg" atomically:YES];
        
        if (maxVal >= acceptableValue) {
            NSLog(@"%i matched point:%d,%d maxVal:%f,tried times:%d",i,maxLoc.x,maxLoc.y,maxVal,i + 1);
            return cv::Rect(maxLoc,cv::Size(templ.cols,templ.rows));
        }
    }
    return cv::Rect();
}

- (Mat)cvMatGrayFromUIImage:(UIImage *)image {
    Mat img_color;
    UIImagetoMat(image,img_color);
    Mat img;
    cvtColor(img_color,img,COLOR_BGR2GRAY);
    return img;
}

- (CGRect)matchWithUIImage:(UIImage*)image {
    Mat img = [self cvMatGrayFromUIImage:image]; //Buffer转换到矩阵
    if (img.cols <= 0 || img.rows <= 0) {
        return CGRectZero;
    }
    cv::Rect rect = [self matchWithMat:img];    
    return CGRectMake(rect.x,rect.y,_templateImage.size.width,_templateImage.size.height);
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)