图像边缘检测,画矩形框及目标的切割

'''

2019.11.22

'''

原理:高斯滤波+滤波算子+查找边缘

原图:

第一步:首先是图像预处理提取特征:img_processing.py

import cv2 as cv
from PIL import Image 
import warnings 
import numpy as np
import matplotlib.pyplot as plt

def pre_processing(image_path):
    image=cv.imread(image_path)
    image=np.array(image,dtype=np.uint8)

    if image.shape[1]<image.shape[0]:
        image=np.rot90(image)         #矩阵旋转90
    
    gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)

    blur=cv.GaussianBlur(image,(13,13),0)

    blur=cv.resize(blur,(0,0),fx=.1,fy=.1)
    gray=cv.resize(gray,(0,0),fx=.1,fy=.1)

    return gray,blur,image

from skimage.exposure import rescale_intensity
'''
函数convolve
功能:实现图像与卷积核的相乘,得到处理后的图像
'''
def convolve(image,kernel):
    (iH,iW)=image.shape[:2]
    (kH,kW)=kernel.shape[:2]

    pad=(kW-1)/2
    pad=int(pad)

    image=cv.copyMakeBorder(image,pad,pad,pad,pad,cv.BORDER_REPLICATE)
    output=np.zeros((iH,iW),dtype='float32')

    for y in np.arange(pad,iH+pad):
        for x in np.arange(pad,iW+pad):
            roi=image[y-pad:y+pad+1,x-pad:x+pad+1]
            k=(roi*kernel).sum()
            output[y-pad,x-pad]=k
    output=rescale_intensity(output,in_range=(0,255))
    output=(output*255).astype("uint8")
    return output






'''
函数:run_kerneler
功能:提供卷积核,并调用conver进行运算,并显示处理后的图像
'''
def run_kerneler(image_path):

    #拉普拉斯算子
    laplacian=np.array((
        [0,1,0],
        [1,-4,1],
        [0,1,0]
    ),dtype='int')
   
   #sobel 算子在x方向
    sobelX=np.array((
       [-1,0,1],
       [-2,0,2],
       [-1,0,1]
    ),dtype='int')

    #prewitt算子
    prewitt=np.array((
       [-1,0,1],
       [-1,0,1],
       [-1,0,1]
    ),dtype='int')

    #sharpening 算子
    sharpen=np.array((
        [0,-1,0],
        [-1,5,-1],
        [0,-1,0]
    ),dtype='int')

    #4,sobel 卷积核 在y方向上
    sobelY=np.array((
                      [-1,-2,-1],
                      [0,0,0],
                      [1,2,1]
                        ),dtype="int")


   #卷积核元组
    kernelBank=(('Laplacian',laplacian),('SobelX',sobelX),('Prewitt',prewitt),('Sharpen',sharpen),('SobelY',sobelY))

    gray,blur,image=pre_processing(image_path)

    for (kernelName,kernel) in kernelBank:
        #灰度
        convolve_gray_output=convolve(gray,kernel)
        #模糊
        convolve_blur_output=convolve(blur,kernel)
        #普通
        # convolve_img_output=convolve(image,kernel)

        # convolve_gray_output=cv.copyMakeBorder(convolve_gray_output,0,50,0,0,cv.BORDER_CONSTANT,value=[255,0,0])
        # convolve_gray_output=cv.putText(convolve_gray_output,kernelName+" and "+"Gray",(10,(convolve_gray_output.shape[0]-20)),cv.FONT_HERSHEY_SIMPLEX,0.35,(100,100,100),1,cv.LINE_AA)
        # convolve_gray_output=cv.rectangle(convolve_gray_output,(0,(convolve_gray_output.shape[0]-50)),(convolve_gray_output.shape[1],convolve_gray_output.shape[0]),(0,0,0),3)

        # convolve_blur_output=cv.copyMakeBorder(convolve_blur_output,0,50,0,0,cv.BORDER_CONSTANT,value=[255,0,0])
        # convolve_blur_output=cv.putText(convolve_blur_output,kernelName+" and "+"Blur",(10,(convolve_blur_output.shape[0]-20)),cv.FONT_HERSHEY_SIMPLEX,0.35,(100,100,100),1,cv.LINE_AA)
        # convolve_blur_output=cv.rectangle(convolve_blur_output,(0,(convolve_blur_output.shape[0]-50)),(convolve_blur_output.shape[1],convolve_blur_output.shape[0]),(0,0,0),3)
        
        # convolve_img_output=cv.copyMakeBorder(convolve_img_output,0,50,0,0,cv.BORDER_CONSTANT,value=[255,0,0])
        # convolve_img_output=cv.putText(convolve_img_output,kernelName+" and "+"Blur",(10,(convolve_img_output.shape[0]-20)),cv.FONT_HERSHEY_SIMPLEX,0.35,(100,100,100),1,cv.LINE_AA)
        # convolve_img_output=cv.rectangle(convolve_img_output,(0,(convolve_img_output.shape[0]-50)),(convolve_img_output.shape[1],convolve_img_output.shape[0]),(0,0,0),3)
        

        cv.imwrite("img"+kernelName+'_Gray'+'.jpg',convolve_gray_output)
        cv.imwrite("img"+kernelName+'_Blur'+'.jpg',convolve_blur_output)
        # cv.imwrite("img"+kernelName+'_Putong'+'.jpg',convolve_img_output)


run_kerneler("0.jpg")

以上代码的解释:将图像高斯滤波或灰度后,选取一个合适的卷积核进行锐化

然后选取一个预处理比较好的图片,这里选择了imgSobelY_Blur.jpg

 

因为图像较小的原因(从网上随意找的),处理效果不是很好,正常情况选择高清的图像

第二步:对目标区域进行进一步的切割,画边框或去掉图片背景(edge.py)。参考博客(https://blog.csdn.net/u013185349/article/details/85098031

import cv2
import numpy as np
import os

def get_image(path):
    #读取图片
    img=cv2.imread(path)
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    return img,gray

def Gaussian_Blur(gray):
    #高斯去噪
    blurred=cv2.GaussianBlur(gray,(9,9),0)
    return blurred


def Sobel_gradient(blurred):
    gradX=cv2.Sobel(blurred,ddepth=cv2.CV_32F,dx=1,dy=0)
    gradY=cv2.Sobel(blurred,ddepth=cv2.CV_32F,dx=0,dy=1)

    gradient=cv2.subtract(gradX,gradY)
    gradient=cv2.convertScaleAbs(gradient)

    return gradX,gradY,gradient

def Thresh_and_blur(gradient):
    blurred=cv2.GaussianBlur(gradient,(9,9),0)
    (_,thresh)=cv2.threshold(blurred,90,255,cv2.THRESH_BINARY)

    return thresh

def image_morphology(thresh):
    #建立一个椭圆核函数
    kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(25,25))

    closed=cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel)
    closed=cv2.erode(closed,None,iterations=0)
    closed=cv2.dilate(closed,None,iterations=2)

    return closed

def findcnts_and_box_point(closed):
    (cnts,_)=cv2.findContours(closed.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)
    c=sorted(cnts,key=cv2.contourArea,reverse=True)[0]

    rect=cv2.minAreaRect(c)
    box=np.int0(cv2.boxPoints(rect))

    return box


def drawcnts_and_cut(original_img,box):
    draw_img=cv2.drawContours(original_img.copy(),[box],-1,(0,0,255),3)

    Xs=[i[0] for i in box]
    Ys=[i[1] for i in box]

    x1=min(Xs)
    x2=max(Xs)

    y1=min(Ys)
    y2=max(Ys)

    hight=y2-y1
    width=x2-x1

    crop_img=original_img[y1:y1+hight,x1:x1+width]
    return draw_img,crop_img




def edge():
    img_path='imgSobelY_Blur.jpg'
    original_img,gray=get_image(img_path)

    blurred=Gaussian_Blur(gray)
    gradX,gradY,gradient=Sobel_gradient(blurred)
    thresh=Thresh_and_blur(gradient)
    closed=image_morphology(thresh)
    box=findcnts_and_box_point(closed)
    draw_img,crop_img=drawcnts_and_cut(original_img,box)
    cv2.imwrite('draw.jpg',draw_img)

if __name__=='__main__':
    edge()

以上代码:https://blog.csdn.net/u013185349/article/details/85098031 这篇博客里讲的很清楚。

效果图:

 

总结:一般情况下只需要第二步即可

 

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页

打赏作者

Spider_man_

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值