图片相似判断

上一篇是做的视频镜头分割,虽然分割成功了,但是视频中有一些镜头中,包含一些含有logo的视频帧,这部分视频是我不想要的,所以就需要识别含有logo图像的,然后把这些帧标记出来。
看了很多其他的实现思路,提到了哈希算法,包括有均值哈希算法、差值哈希算法、感知哈希算法。开始的时候,这三种算法都试过,发现都有问题,准确率很低,这时仔细看了每一帧的logo图,才发现logo图的大小不一样,也就是帧之间,logo图可能放大或者缩小了,那么用哈希算法判断的结果就很难去评估这个准确性。因为需要用到阈值,而这个阈值很难设定,所以就放弃了这个方案。
具体哈希实现,大家可以参考以下地址:
哈希算法实现

接下来就是按照其他思路来计算

一、LOGO图片大小不一

由于每一帧的logo图大小不一样,那么在判断之前,必须将logo图片的大小统一,这样才能根据图像数据进行比较判断

二、灰度值

由于图片需要用判断,那么尽量减少颜色的干扰,所以在处理的时候,需要将图片中的颜色去除,所以统一采用灰度值进行处理

三、计算每一行的平均值

图片统一尺寸后,每一行的元素记录了这张图片的特征,那么用每一行的灰度值的均值标识这一行的特征

四、方差

将上一步计算的平均值,求方差,也就是得到了这张图的所有灰度值的方差,然后通过两张图的方差比较,进行相似度的判断。具体方差的判断,我们可以根据多张图的方差曲线图,来做具体的阈值处理。

接下来就是具体的代码实现

1、提取图片数据

#这是一张logo图,用于判断依据的图。由于所使用的logo图色彩差异很大,所以先进行了二值化,方便后期处理
default_img = cv2.imread(default_img_path, cv2.IMREAD_GRAYSCALE)
ret, default_binary = cv2.threshold(default_img, 200, 255, cv2.THRESH_BINARY)

有了上面的原图,下面就是提取一帧图像中的logo图

#这里只包含了部分代码,读取图像,然后找到logo图的位置,从原图中截下对应区域的原图数据
    while success:
        success, frame = cap.read()
        if not success:
            break
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 转换成灰度
        shape = np.shape(gray)
        height = shape[0]
        width = shape[1]

        '''
            1、二值化
        '''
        ret, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)

        '''
            2、找到需要截取的中间区域的图片
                从中间开始,往前/后找到第一个全部为0的一列,
        '''
        position = find_logo_position(binary, width, height)
        if position is None:
            print("找寻logo位置信息失败 : {0}".format(frame_index))
        else:
            print("找寻logo位置信息成功 : {0}".format(frame_index))
            start_sub_row = position[0]
            end_sub_row = position[1]
            start_sub_col = position[2]
            end_sub_col = position[3]
            # print("{0},{1},{2},{3}".format(start_sub_row, end_sub_row, start_sub_col, end_sub_col))
            frame_sub = frame[start_sub_row:end_sub_row, start_sub_col:end_sub_col]
            is_logo = compare_sub(default_binary, frame_sub)
            print("是否是logo图 : {0} = {1}".format(frame_index, is_logo))

        frame_index += 1

二、计算和比较

def compare_sub(src_binary, sub_frame):
    src_shape = np.shape(src_binary)
    src_h = src_shape[0]
    src_w = src_shape[1]
    sub_shape = np.shape(sub_frame)
    sub_h = sub_shape[0]
    sub_w = sub_shape[1]

    # 由于参考的源已经是最小像素,则新图如果尺寸过小,忽略
    if (src_h - sub_h) > 20 or (src_w - sub_w) > 20:
        return False

    # 以sub的高为固定值,计算sub的理论宽度,比较实际宽度与理论宽度
    theory_sub_width = src_w * sub_h // src_h
    if abs(theory_sub_width - sub_w) > 6:
        return False

    # 对图片进行缩放处理
    crop_size = (src_w, src_h)
    sub_new = cv2.resize(sub_frame, crop_size, interpolation=cv2.INTER_CUBIC)
    sub_gray = cv2.cvtColor(sub_new, cv2.COLOR_BGR2GRAY)  # 转换成灰度
    ret, sub_binary = cv2.threshold(sub_gray, 200, 255, cv2.THRESH_BINARY)  # 二值化

    # 计算每一行的平均值
    src_sum_row = np.sum(src_binary, axis=1)
    src_sum_row = src_sum_row / src_w  # 计算每行的均值
    sub_sum_row = np.sum(sub_binary, axis=1)
    sub_sum_row = sub_sum_row / src_w

    ss_src = get_diff(src_sum_row)
    ss_sub = get_diff(sub_sum_row)

    ss = ss_sub - ss_src
    ss = np.fabs(ss)


    n = 0
    for value in ss:
        if value <= 1.0:
            n += 1

    if (n / len(ss)) > 0.9:
        x = range(src_h)
        plt.figure("avg")
        plt.plot(x, ss_src, marker="*", label="$walk01$")
        plt.plot(x, ss_sub, marker="*", label="$walk03$")
        plt.title("compare")
        plt.legend()
        plt.show()
        return True
    else:
        return False

3、计算方差

def get_diff(source):
    size = len(source)
    ave_src = sum(source) / size  # 总的平均值
    s_src = source - ave_src  # 计算每个值与平均值的差值
    ss_src = s_src * s_src / size  # 方差
    return ss_src

说明
在上面比较的代码中,我对logo图的方差与原图logo方差的差值进行了取绝对值,这是因为我需要看两张图在同一个位置特征上的波动情况。然后根据波动情况的范围,来判断这个位置是否相近,当走势中准确度达到90%时,我就认为这张图是原图。
这个比较和判断结果,我是通过多张图的logo解析结果,方差变化情况决定的。以下是对应的参考情况。

比较图1

比较图2

通过上面两个图,我们就能大概的选择自己需要判断的范围了。

以上内容是我自己根据一些文章,然后结合自己的需求,改进的方案,有问题或者需要探讨的,欢迎留言讨论

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容