OpenCV计算两幅图像的EMD度量

这篇博客介绍了如何利用OpenCV库在Python中计算两幅图像的Earth Mover's Distance (EMD)。首先,文章解释了EMD的基本概念,并提供了相关资源。接着,展示了如何从RGB图像转换为HSV并计算直方图,然后将直方图转换为适合EMD计算的签名。最后,给出了计算EMD的Python代码示例,并提供了C++版本的参考资料。
摘要由CSDN通过智能技术生成

OpenCV计算两幅图像的EMD度量

EMD度量:

相关基础

https://blog.csdn.net/wangdonggg/article/details/32329879
这位大哥说的很好了,先就不搬运了,后面有空再整理

函数介绍

https://docs.opencv.org/4.5.2/d6/dc7/group__imgproc__hist.html

Python版本

看到现在有的都是C++版本的代码,自己基于Python写了一个

import cv2 as cv2
import numpy


def get_hist(img_in):
    img = img_in.copy()
    hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
    # cv2.imshow("hsv", hsv)
    # calcHist(&hsv[i], 1, ch, noArray(), hist[i], 2, histSize, ranges, true) # CPP
    # mask = cv2.bitwise_xor(img, img)
    channels = [0, 1, 2]
    histSize = [8, 10, 10]
    ranges = [0, 180, 0, 256, 0, 256]
    hist = cv2.calcHist([hsv], channels, None, histSize, ranges)
    # cv2.imshow("hist", hist)
    hist = cv2.normalize(hist, hist, 1.0, 0.0, cv2.NORM_MINMAX)
    # print(hist)
    return hist


def hist2signature(hist):
    histSize = hist.shape
    assert len(histSize) == 3
    signature = numpy.zeros(shape=(histSize[0] * histSize[1] * histSize[2], 4), dtype=numpy.float32)
    for h in range(histSize[0]):
        for s in range(histSize[1]):
            for v in range(histSize[2]):
                idx = (h + 1) * (s + 1) * (v + 1) - 1
                signature[idx][0] = hist[h][s][v]
                signature[idx][1] = h
                signature[idx][2] = s
                signature[idx][3] = v
    return signature


if __name__ == '__main__':
    path_rgb = r'./video/scivideo/vid_rgb_frame1.png'
    img_rgb = cv2.imread(path_rgb)
    # print(img_rgb)
    # img_down = cv2.pyrUp(cv2.pyrDown(img_rgb))
    img_down = cv2.pyrDown(img_rgb)
    # cv2.imshow("img_rgb", img_rgb)
    # 计算直方图
    hist_gt = get_hist(img_rgb)
    hist_down = get_hist(img_down)
    # EMD算法要求的数据格式不是计算的hist,而是(val, h, s, v) * (h_bin*s_bin*v_bin)  因此需要转换
    signature_hist = hist2signature(hist_down)
    signature_gt = hist2signature(hist_gt)
    # 计算 EMD
    retval, lowerBound, flow = cv2.EMD(signature_hist, signature_gt, cv2.DIST_L2)
    print(retval)
    cv2.waitKey(0)

C++

先贴上别的大佬的实现吧

https://blog.csdn.net/qq_30815237/article/details/86807253?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242

https://blog.csdn.net/z827997640/article/details/79841372

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值