c++ - 比较图像的相似性

标签 c++ opencv

我试图自动判断两个数字是否相似。您可以在此处找到三个示例: http://imgur.com/N5SeaQW,IZYszx5,4RxLy4o

第一张图和第二张和第三张图不一样,但是第二张和第三张是一样的(不完全一样,仔细看还是有些细微的差别)

我的代码(大部分来自 OpenCV 文档中的特征单应性示例)读取两个不同的图像,计算它们的关键点和描述符(使用 SIFT,但我也尝试过 SURF 和 ORB),使用 FlannBasedMatcher 和计算单应矩阵。从可选的状态 vector 中,我计算了内点与关键点总数的比率,以计算“距离”。

但是,计算出的距离并没有做出正确的区分:

d(img1, img2) = 0.296296
d(img1, img3) = 0.407407
d(img2, img3) = 0.362069

所以我无法得出图像 1 与图像 2 不同、图像 1 与图像 2 不同以及图像 2 等于图像 3 的结论。

是否有更好的方法或指标来确定哪些图像相似?

Mat img_object = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
Mat img_scene = imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE );

//-- Step 1: Detect keypoints using SIFT
Ptr<FeatureDetector > detector;
detector = new SiftFeatureDetector();
std::vector<KeyPoint> keypoints_object, keypoints_scene;
detector->detect( img_object, keypoints_object );
detector->detect( img_scene, keypoints_scene );

//-- Step 2: Calculate descriptors (feature vectors)
Ptr<DescriptorExtractor > extractor;
extractor = new SiftDescriptorExtractor;
Mat descriptors_object, descriptors_scene;
extractor->compute( img_object, keypoints_object, descriptors_object );
extractor->compute( img_scene, keypoints_scene, descriptors_scene );

//-- Step 3: Matching descriptor vectors using FLANN matcher
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptors_object, descriptors_scene, matches );

//-- Step 4: Compute homography matrix and status vector
std::vector<Point2f> obj;
std::vector<Point2f> scene;
for( int i = 0; i<matches.size(); i++){
    obj.push_back( keypoints_object[ matches[i].queryIdx ].pt );
    scene.push_back( keypoints_scene[ matches[i].trainIdx ].pt );
}
std::vector<uchar> status;
Mat H = findHomography( obj, scene, status, CV_RANSAC, 3 );

//-- Step 5: Compute inliers/status.size
int inliers = 0;
for(int i = 0; i<status.size(); i++){
    inliers += status[i];
}
printf("Percentage of inliers: %f \n",( (float) inliers)/( (float) status.size() ));

最佳答案

Is there a better method or metric to decide which images are similar?

为什么不找出所有的圆并计算它们之间的距离?

代码如下:

Point2i center(vector<Point2i> contour)
{
    Moments m = moments(contour);

    return Point2i(m.m10/m.m00, m.m01/m.m00);
}


vector<Point2i> getCenters(Mat img)
{
    vector<vector<Point2i> > contours;

    threshold(img, img, 0, 255, THRESH_OTSU);

    findContours(img, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

    vector<Point2i> result(contours.size());

    for (int i=0; i<contours.size(); i++)
    {
        result[i] = center(contours[i]);
    }

    return result;
}


double distanceCenter(Point2i center1, Point2i center2)
{
    return (center1.x - center2.x)*(center1.x - center2.x) + (center1.y - center2.y)*(center1.y - center2.y);
}


double distanceCenters(vector<Point2i> centers1, vector<Point2i> centers2)
{
    if (centers1.size() != centers2.size())
    {
        return -1;
    }
    else
    {
        double result = 0;

        for (int i=0; i<centers1.size(); i++)
        {
            double min = INT_MAX;

            for (int j=0; j<centers2.size(); j++)
            {
                double dist = distanceCenter(centers1[i], centers2[j]);
                if (dist < min)
                {
                    min = dist;
                }
            }

            result += min;
        }

        return result;
    }
}


int main()
{
    Mat img1 = imread("image1.png", CV_LOAD_IMAGE_GRAYSCALE),
        img2 = imread("image2.png", CV_LOAD_IMAGE_GRAYSCALE);

    cout << distanceCenters(getCenters(img1), getCenters(img2)) << endl;

    return 0;
}

和结果:

distance between 1 and 2: 14676

distance between 2 and 3: 393

关于c++ - 比较图像的相似性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14756533/

相关文章:

opencv - Windows 上的 FFMPEG(用于 H.264 RTSP 解码)

c++ - 通过 CRTP 的基类引用访问派生类的 constexpr 成员变量

c++ - 读取输入以构造对象

c++ - 除非使用某些寄存器,否则函数 Hook 会崩溃

android - 使用OpenCV在Android上进行多对象检测

c - 使用opencv播放视频

c++ - 破译 C/C++ 函数指针类型定义的工具

c++ - 如何以编程方式更改主音量?

python - 使用 OpenCV 检测破损形状

python - 使用 OpenCV 从图像背景中去除波浪噪声