提取一张图像内红框标注的区域-python

参考博客https://blog.csdn.net/qq_40456669/article/details/93375709https://blog.csdn.net/weixin_43181409/article/details/104778084

import cv2
import numpy as np
import os
import json

def show(img_name, img): # 显示图像
    cv2.namedWindow(str(img_name), cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
    cv2.resizeWindow(str(img_name), 960, 1440)
    cv2.imshow(str(img_name), img)
    cv2.waitKey(0)

def boxes_extract(img_1, img_2, name): # 提取ROI
    image_ref_rgb = cv2.imread(img_1) # 带红色标注框的参考图像
    image_ori_rgb = cv2.imread(img_2) # 原图篡改图像
    ROI = np.zeros(image_ref_rgb.shape, np.uint8)  # 创建与原图同尺寸的空numpy数组,用来保存ROI信息
    image_1_hsv = cv2.cvtColor(image_ref_rgb, cv2.COLOR_BGR2HSV) # HSV空间内分离颜色
    low_hsv = np.array([0, 43, 46])
    high_hsv = np.array([10, 255, 255])
    binary = cv2.inRange(image_1_hsv, lowerb=low_hsv, upperb=high_hsv) # 根据红色hsv上下限转为二值图像
    binary = cv2.blur(binary, (3, 3)) # KEY STEP: 模糊处理减少瑕疵点
    # show('target zones', binary)
    contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, # EXTERNAL选择最外框
                                           cv2.CHAIN_APPROX_SIMPLE)  # 查找所有轮廓信息并保存于contours数组中
    # print(len(contours))
    left_up_corner_set = {} # 创建字典{‘轮廓标号’:‘左上角点坐标’} 保存裁剪区域左上角点集合
    corners_json = {}
    if not os.path.exists('./log'):
        os.mkdir('./log')
    for i in range(len(contours)):  # 基于轮廓数量处理每个轮廓
        epsilon = 0.5 * cv2.arcLength(contours[i], True)  # arcLength计算轮廓周长,True表示目标轮廓是闭合的
                                                           # epsilon为准确率参数,表示实际轮廓到近似轮廓的最大距离(调参)
        approx = cv2.approxPolyDP(contours[i], epsilon, True)  # 把轮廓形状近似为边数较少的形状,边数由指定的epsilon决定
        mm = cv2.moments(contours[i])
        if mm['m00'] != 0:
            cx = int(mm['m10'] / mm['m00'])
            cy = int(mm['m01'] / mm['m00']) # 计算轮廓重心位置坐标
            color = image_ref_rgb[cy][cx]
            color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")"
            p = cv2.arcLength(contours[i], True)
            area = cv2.contourArea(contours[i]) # 计算轮廓面积
            # 分析几何形状
            corners = len(approx)
            if corners <= 4 and (color[2] >= 10 or color[0] >= 10) and area > 1000:  # 判定条件根据ROI特点进行调整
                rect = cv2.minAreaRect(contours[i])   # 找到最小外接矩形,该矩形可能有方向
                box = cv2.boxPoints(rect)   # box是四个点的坐标
                # x, y, w, h = cv2.boundingRect(contours[i])  #寻找正矩形 返回x,y是矩阵左上点的坐标,w,h是矩阵的宽和高
                # box = [(x, y), (x + w, y), (x + w, y + h), (x + h, y)]
                # cv2.rectangle(ROI, (x, y), (x + w, y + h), (0, 255, 0), 2)
                box = np.array([np.array(i, np.int) for i in box])
                rbx = max(box[i][0] for i in range(4))
                rby = max(box[i][1] for i in range(4))
                lux = min(box[i][0] for i in range(4))
                luy = min(box[i][1] for i in range(4))
                crop = image_ori_rgb[luy:rby, lux:rbx] # 裁剪篡改区域
                if not os.path.exists('./crop/' + name):
                    os.mkdir('./crop/' + name)
                cv2.imwrite('./crop/' + name + '/crop' + str(i).zfill(4) + ".jpg", crop) # 保存裁剪区域
                left_up_corner_set[str(i).zfill(4)] = (lux, luy) # 将左上角点坐标写入json
                corners_json[str(i).zfill(4)] = (float(lux), float(luy))
                cv2.drawContours(ROI, [box], 0, (255, 255, 255),
                    -1)  # 在ROI空画布上画出轮廓,并填充白色(最后的参数为轮廓线条宽度,如果为负数则直接填充区域)
                # if not os.path.exists('./mask/' + name):
                #     os.mkdir('./mask/' + name)
                # cv2.imwrite("./mask/" + str(name) + "/img_mask" + str(i).zfill(4) + ".jpg", ROI)
                # imgroi = ROI & image_ori_rgb  # ROI和原图进行与运算,筛出原图中的ROI区域
                # cv2.imwrite("./mask/" + str(name) + "/img_roi" + str(i).zfill(4) + ".jpg", imgroi)
                # show("ROI", imgroi)
    with open("./log/" + name + ".json", 'w') as f:
        json.dump(corners_json, f)
    return name, image_ori_rgb, left_up_corner_set

if __name__ == "__main__":

    ref_list = os.listdir('./reference')
    fake_list = os.listdir('./reals')
    for i in range(len(ref_list)):
        img_ref = './reference/' + ref_list[i]
        img_fake = './reals/' + fake_list[i]
        name = ref_list[i][:-4]

        name, image_ori_rgb, left_up_corner_set = boxes_extract(img_ref, img_fake, name) # 篡改


  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值