opencv提取图像中矩形区域并裁剪

概述

代码适用于图像中仅有一个矩形的情况,对图像中的矩形区域进行边缘的做标提取,完成对矩形区域的裁剪,裁剪完后对图像进行了填充、旋转(若图像倾斜)

思路

  1. 读取图像,将图像转成灰度图
  2. 对图像进行开运算,将烟盒以外的污点去除
  3. 提取图像最小外接矩形
  4. 通过最小外接矩形的四个点坐标对图像进行填充
  5. 将图像翻转至水平角度
  6. 用图像开操作(先腐蚀、后膨胀)
  7. 旋转图像(图像不水平情况下)
  8. 写入覆盖原图

实现

import os
import numpy as np
import cv2


def crop_picture_pro(path):
    img_path = path
    files = os.listdir(img_path)
    files.sort()

    for bmpFile in files:
        if bmpFile.endswith('.bmp'):

            # 读取图像并转化为灰度图
            image = cv2.imread((img_path + str(bmpFile)))
            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            gray = cv2.bitwise_not(gray)

            h, w = gray.shape
            # 对图像进行开运算,将矩形以外的污点去除
            kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
            dst = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel, None, None, 5)
            # 提取图像最小外接矩形
            thresh = cv2.threshold(dst, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
            coords = np.column_stack(np.where(thresh > 0))
            rect_origin = cv2.minAreaRect(coords)
            # 通过最小外接矩形的四个点坐标对图像进行填充
            # top bottom left right
            if int(rect_origin[0][0]) >= h / 2 and int(rect_origin[0][1]) >= w / 2:
                img_modify = cv2.copyMakeBorder(image, 0, h, 0, w, cv2.BORDER_CONSTANT, value=[255, 255, 255])
            elif int(rect_origin[0][0]) > h / 2 and int(rect_origin[0][1]) < w / 2:
                img_modify = cv2.copyMakeBorder(image, 0, h, w, 0, cv2.BORDER_CONSTANT, value=[255, 255, 255])
            elif int(rect_origin[0][0]) < h / 2 and int(rect_origin[0][1]) < w / 2:
                img_modify = cv2.copyMakeBorder(image, h, 0, w, 0, cv2.BORDER_CONSTANT, value=[255, 255, 255])
            else:
                img_modify = cv2.copyMakeBorder(image, h, 0, 0, w, cv2.BORDER_CONSTANT, value=[255, 255, 255])

            # 将图像翻转至水平角度
            gray_modify = cv2.cvtColor(img_modify, cv2.COLOR_BGR2GRAY)
            gray_modify = cv2.bitwise_not(gray_modify)
            # 用图像开操作(先腐蚀、后膨胀)
            kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
            dst_modify = cv2.morphologyEx(gray_modify, cv2.MORPH_OPEN, kernel, None, None, 5)
            # 旋转图像
            thresh = cv2.threshold(dst_modify, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
            coords_modify = np.column_stack(np.where(thresh > 0))
            angle = cv2.minAreaRect(coords_modify)[-1]
            if angle < -45:
                angle = -(90 + angle)
            else:
                angle = -angle

            (h_modify, w_modify) = img_modify.shape[:2]
            center = (w_modify // 2, h_modify // 2)
            M = cv2.getRotationMatrix2D(center, angle, 1.0)
            img_rotate = cv2.warpAffine(img_modify, M, (w_modify, h_modify), flags=cv2.INTER_CUBIC,
                                        borderMode=cv2.BORDER_REPLICATE)
            # img_rotate = cv2.resize(img_rotate, (1944, 2592))
            # 对图像进行裁剪,提取矩形区域
            gray_rotate = cv2.cvtColor(img_rotate, cv2.COLOR_BGR2GRAY)
            gray_rotate = cv2.bitwise_not(gray_rotate)
            # 用图像开操作(先腐蚀、后膨胀)
            kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
            gray_rotate = cv2.morphologyEx(gray_rotate, cv2.MORPH_OPEN, kernel, None, None, 3)

            thresh = cv2.threshold(gray_rotate, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
            coords_rotate = np.column_stack(np.where(thresh > 0))
            rect_rotate = cv2.minAreaRect(coords_rotate)
            box_rotate = cv2.boxPoints(rect_rotate)

            box_rotate = np.int0(box_rotate)
            x_min = min([int(box_rotate[0][0]), int(box_rotate[1][0]), int(box_rotate[2][0]), int(box_rotate[3][0])])
            y_min = min([int(box_rotate[0][1]), int(box_rotate[1][1]), int(box_rotate[2][1]), int(box_rotate[3][1])])
            x_max = max([int(box_rotate[0][0]), int(box_rotate[1][0]), int(box_rotate[2][0]), int(box_rotate[3][0])])
            y_max = max([int(box_rotate[0][1]), int(box_rotate[1][1]), int(box_rotate[2][1]), int(box_rotate[3][1])])

            img_new = img_rotate[int(x_min):int(x_max), int(y_min):int(y_max)]
            cv2.imwrite((img_path + str(bmpFile)), img_new)

    print("Crop pictures finished")

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐