• opencv python截取圆形区域



    前言

    如果你只要图片中圆形的区域,其余的留白,那么可以进行以下操作。


    一、先进行剪切操作

    圆形区域占图片可能不多,多余的部分不要。
    看下图。
    在这里插入图片描述
    只要纽扣电池内部和少许的边缘部分,其余黑色背景部分不需要。
    先沿着纽扣电池的边缘剪切出来感兴趣的区域。
    有2个方法,用寻找轮廓外接圆的方法,或者基尔霍夫圆的方法。
    在这里以轮廓外接圆方法为例。
    代码如下:

    import cv2
    import numpy as np
    
    image = cv2.imread('F:\Siamese-pytorch-master\datasets\images_background\quebian_Hander/20220724-112303-336.jpg')
    image=cv2.resize(image,(800,600))#缩放一下
    img=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 灰度图
    # 二值化  这个位置要注意二值化和反二值化,看你原图是什么样子的底色
    # ret , thresh = cv2.threshold(img, 230, 255, cv2.THRESH_BINARY_INV)
    # ret , thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    ret , thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    dot=[]  # 用来保存所有轮廓返回的坐标点。
    for c in contours:
        # 找到边界坐标
        min_list=[] # 保存单个轮廓的信息,x,y,w,h,area。 x,y 为起始点坐标
        x, y, w, h = cv2.boundingRect(c)  # 计算点集最外面的矩形边界
        min_list.append(x)
        min_list.append(y)
        min_list.append(w)
        min_list.append(h)
        min_list.append(w*h) # 把轮廓面积也添加到 dot 中
        dot.append(min_list)
    
    # 找出最大矩形的 x,y,w,h,area
    max_area=dot[0][4] # 把第一个矩形面积当作最大矩形面积
    for inlist in dot:
        area=inlist[4]
        if area >= max_area:
            x=inlist[0]
            y=inlist[1]
            w=inlist[2]
            h=inlist[3]
            max_area=area
    # 在原图上画出最大的矩形  这部分实际上是对边缘再扩展一下,避免剪切的圆不够完整
    print(x,y,w,h)
    if y>=60:
        new_w=60
    elif y>=50:
        new_w=50
    elif y>=40:
        new_w=40
    elif y>=30:
        new_w=30
    elif y>=20:
        new_w=20
    elif y>=10:
        new_w=10
    
    x0=x-int(new_w/2)
    y0=y-int(new_w/2)
    w=w+new_w
    h=h+new_w
    print(x0,y0,w,h)
    # cv2.rectangle(image, (x0, y0), (x + w, y + h), (0, 255, 0), 1)
    
    crop = image[y0:y0+h, x0:x0+w]
    cv2.imshow('crop',crop)
    cv2.imwrite("crop.jpg",crop)
    cv2.waitKey(0)
    cv2.destroyWindow()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    代码执行以后可以看下剪切效果。大致如下。
    在这里插入图片描述
    以上代码是单张图片。
    执行一下代码可以批量处理图片。
    注意:如果你的代码报错,注意下二值化的这行代码,是THRESH_BINARY_INV还是THRESH_BINARY。

    # -*- coding:utf-8 -*-
    # from re import X
    import cv2
    import numpy as np
    
    from glob import glob
    import os
    
    img_path = glob("F:\Siamese-pytorch-master\datasets\images_background\character01/*.jpg")
    path_save = "F:\Siamese-pytorch-master\datasets\images_background\quebian_Hander/"
    
    
    for i,file in enumerate(img_path):
        name = os.path.join(path_save, "%d.jpg"%i)
        image = cv2.imread(file)
        print(file,i)
        image=cv2.resize(image,(800,600))
        img=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        img = cv2.bilateralFilter(img,9,75,75)
        ret , thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)
        contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        
        dot=[]  # 用来保存所有轮廓返回的坐标点。
        for c in contours:
            # 找到边界坐标
            min_list=[] # 保存单个轮廓的信息,x,y,w,h,area。 x,y 为起始点坐标
            x, y, w, h = cv2.boundingRect(c)  # 计算点集最外面的矩形边界
            min_list.append(x)
            min_list.append(y)
            min_list.append(w)
            min_list.append(h)
            min_list.append(w*h) # 把轮廓面积也添加到 dot 中
            dot.append(min_list)
    
    # 找出最大矩形的 x,y,w,h,area
        max_area=dot[0][4] # 把第一个矩形面积当作最大矩形面积
        for inlist in dot:
            area=inlist[4]
            if area >= max_area:
                x=inlist[0]
                y=inlist[1]
                w=inlist[2]
                h=inlist[3]
                max_area=area
    # 在原图上画出最大的矩形
        print(x,y,w,h)
        if y>=60:
            new_w=60
        elif y>=50:
            new_w=50
        elif y>=40:
            new_w=40
        elif y>=30:
            new_w=30
        elif y>=20:
            new_w=20
        elif y>=10:
            new_w=10
        elif y>=5:
            new_w=5
        else:
            new_w=0
    
        x0=x-int(new_w/2)
        y0=y-int(new_w/2)
        w=w+new_w
        h=h+new_w
        print(x0,y0,w,h)
        # cv2.rectangle(image, (x0, y0), (x0 + w , y0 + h), (0, 255, 0), 1)
        crop = image[y0:y0+h, x0:x0+w]
        cv2.imwrite(name,crop)
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    批量以后效果类似下图。基本上裁减掉了不需要的部分。
    在这里插入图片描述

    二、去除背景

    执行以下代码。

    import cv2
    import numpy as np
    from glob import glob
    import os
     
    
    img_path = glob("F:\DEMO_CODE\demo\ML\qieyuan/*.jpg")
    path_save = "F:\DEMO_CODE\demo\ML\qieyuan/"
    
    for i,file in enumerate(img_path):
        name = os.path.join(path_save, "%d.jpg"%i)
        image = cv2.imread(file)
        gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
        _, binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)
        contours, _ = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
        for cont in contours:
            (x, y), radius = cv2.minEnclosingCircle(cont)
            if radius>200:
                ming=cv2.circle(image,(int(x),int(y)),int(radius), (0, 0, 255), 2)
                print("radius is ")
                print(radius)
                print((x, y))   
                roi = np.zeros(image.shape[:2], np.uint8)
                roi = cv2.circle(roi,(int(x),int(y)), int(radius), 255, cv2.FILLED)
                mask = np.ones_like(image) * 255
                mask = cv2.bitwise_and(mask, image, mask=roi) + cv2.bitwise_and(mask, mask, mask=~roi)
                cv2.imwrite(name,mask)
                print(i,name)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    效果如下:
    在这里插入图片描述
    不要的部分就变成白色了


    总结

    卷积神经网络的不一定需要图片预处理,有时候预处理反而得到不好的结果。但是也可以尝试一下,也许结果更好。

  • 相关阅读:
    【Spring】IDEA&spring-mybatis的整合----关于配置文件的整合、AOP事务处理(配置&注解)
    数据库有故障怎么了?
    缓存篇—缓存雪崩、缓存击穿、缓存穿透
    java8日期时间格式化与解析
    选择正确的 React 状态管理解决方案的指南
    UEditorPlus v2.4.0发布 Word图片粘贴重构,功能样式优化
    软件测试/人工智能丨深入人工智能软件测试:PyTorch引领新时代
    第一章: Mysql体系结构和存储引擎
    时间序列预测(9) — Informer源码详解与运行
    zigbee笔记:七、zigbee系统电源管理与睡眠唤醒
  • 原文地址:https://blog.csdn.net/linmuquan1989/article/details/126315114