基于Python+OpenCV自动提取并裁切ROI(感兴趣区域)

主要记录一下自己在找资料并实现的过程

  • 一、基本思路
  • 二、代码实例

一、基本思路

通过OpenCV读取图片,进行二值化操作后寻找轮廓,并且将轮廓保存再与原图片进行位与运算,完成裁切效果。本项目中主要提取图片中的圆形以及三角形。

二、代码实例

import cv2 as cv
import numpy as np


src = cv.imread(r"D:\test5.jpg") # 读取图片
ROI = np.zeros(src.shape, np.uint8) # 创建与原图同尺寸的空numpy数组,用来保存ROI信息

gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) # 灰度化
ret, binary = cv.threshold(gray,
			   0, 255, 
			   cv.THRESH_BINARY_INV | cv.THRESH_TRIANGLE) # 自适应二值化
			   
out_binary, contours, hierarchy = cv.findContours(binary, 
			   cv.RETR_EXTERNAL,
			   cv.CHAIN_APPROX_SIMPLE) # 查找所有轮廓,每个轮廓信息保存于contours数组中

for cnt in range(len(contours)): # 基于轮廓数量处理每个轮廓
    # 轮廓逼近,具体原理还需要深入研究
    epsilon = 0.01 * cv.arcLength(contours[cnt], True)
    approx = cv.approxPolyDP(contours[cnt], epsilon, True) # 保存逼近结果的顶点信息
    							   # 顶点个数决定轮廓形状 
    # 计算轮廓中心位置							   
    mm = cv.moments(contours[cnt])
    if mm['m00'] != 0:
        cx = int(mm['m10'] / mm['m00'])
        cy = int(mm['m01'] / mm['m00'])
        color = src[cy][cx]
        color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")"
        p = cv.arcLength(contours[cnt], True)
        area = cv.contourArea(contours[cnt])
        
        # 分析几何形状
        corners = len(approx)
        if corners == 3 and (color[2]>=150 or color[0]>=150) and area>1000:  # 一系列判定条件是由该项目的特点所调整的
            cv.drawContours(ROI, contours, cnt, (255, 255, 255), -1)  # 在ROI空画布上画出轮廓,并填充白色(最后的参数为轮廓线条宽度,如果为负数则直接填充区域)
            imgroi = ROI & src  # ROI和原图进行与运算,筛出原图中的ROI区域
            cv.imshow("ROI", imgroi)
            cv.imwrite(r"D:\ROI.jpg")
            
        if corners >= 10 and (color[2]>=150 or color[0]>=150) and area>1000:          
    	    cv.drawContours(ROI, contours, cnt, (255, 255, 255), -1)
            imgroi = ROI & src
            cv.imshow("ROI",imgroi)
            cv.imwrite(r"D:\ROI.jpg")

            
cv.waitKey(0)
cv.destroyAllWindows()         

效果如下
基于Python+OpenCV自动提取并裁切ROI(感兴趣区域)_第1张图片
总体上效果还可以接受,已经能够大幅度减少神经网络的计算量了。

你可能感兴趣的:(基于Python+OpenCV自动提取并裁切ROI(感兴趣区域))