工业圆型检测

圆型凹槽检测(python+opencv)

亮度均匀算法+霍夫+分块滤波

原图:
在这里插入图片描述

# -*- coding: utf-8 -*-
"""
Created on Wed Jan  6 16:01:52 2021

@author: HUANGYANGLAI
"""

import cv2 as cv
import math
import numpy as np
import matplotlib.pyplot as plt


def unevenLightCompensate(img, blockSize):
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)#读取灰度图片
    average = np.mean(gray)#求均值

    rows_new = int(np.ceil(gray.shape[0] / blockSize))#返回上整数
    cols_new = int(np.ceil(gray.shape[1] / blockSize))
    print('rows_new',rows_new)
    print('cols_new',cols_new)
    blockImage = np.zeros((rows_new, cols_new), dtype=np.float32)
    
    for r in range(rows_new):
        for c in range(cols_new):
            rowmin = r * blockSize
            rowmax = (r + 1) * blockSize
            if (rowmax > gray.shape[0]):#到达边界
                rowmax = gray.shape[0]
            colmin = c * blockSize
            colmax = (c + 1) * blockSize
            if (colmax > gray.shape[1]):#到达边界
                colmax = gray.shape[1]

            imageROI = gray[rowmin:rowmax, colmin:colmax]
            temaver = np.mean(imageROI)
            blockImage[r, c] = temaver

    blockImage = blockImage - average
    blockImage2 = cv.resize(blockImage, (gray.shape[1], gray.shape[0]), interpolation=cv.INTER_CUBIC)
    gray2 = gray.astype(np.float32)
    dst = gray2 - blockImage2
    dst = dst.astype(np.uint8)
    dst = cv.GaussianBlur(dst, (3, 3), 0)
    print('haha',dst.shape)
    dst = cv.cvtColor(dst, cv.COLOR_GRAY2BGR)

    return dst


def rgb2gray(img):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    for i in range(h):
        for j in range(w):
            img1[i,j]=0.144*img[i,j,0]+0.587*img[i,j,1]+0.299*img[i,j,1]
    return img1



def dis(x1,x2,y1,y2):
    return (x1-x2)**2+(y1-y2)**2


def FindPointsOnCircle(Image,cx,cy,r,dr):
    out=Image.copy()
    H,W=Image.shape
    for x in range(W):
        for y in range(H):
            d=dis(x,cx,y,cy) 
            if d<(r-dr)**2 or d>(r+dr)**2:
                out[y,x]=0
    return out

def findmaxRadius( image, Cir, dr):#image是大致区域范围,cir在圆形范围内检测到的圆形,dr带宽
    CirIndex=[]
    (H,W)=image.shape
    H=H/2
    W=W/2
    for data in Cir:
        if data[0]>= W-dr and data[0] <=W+dr and data[1]>= H-dr and data[1] <=H+dr:
            CirIndex.append(data)
        
    return CirIndex

def first_order(img):#一阶画圆
    otsuimage=img
    sobelx=cv.Sobel(otsuimage,cv.CV_64F,1,0,ksize=3)
    sobelx=cv.convertScaleAbs(sobelx)
    sobely=cv.Sobel(otsuimage,cv.CV_64F,0,1,ksize=3)
    sobely=cv.convertScaleAbs(sobely)
    sobelimage=cv.addWeighted(sobelx,0.5,sobely,0.5,0)
    return sobelimage

def nightcircle(img):
    data=img
    data0=data[0:3]
    data1=data[3:6]
    data2=data[6:9]
    
    indey0=np.argsort(data0,0)[:,0]
    data0=data0[indey0,:] 
    indey1=np.argsort(data1,0)[:,0]
    data1=data1[indey1,:] 
    indey2=np.argsort(data2,0)[:,0]
    data2=data2[indey2,:] 
    print('0',data0)
    print('1',data1)
    print('2',data2)
    
    data=np.vstack((data0,data1,data2))
    return data
def Houghtrans(img,para1,para2,minRadius,maxRadius):
    circle=cv.Houghcircles(img,cv.HOUGH_GRADIENT,1,para1,param1=1,param2=para2,minRadius=minRadius,maxRadius=maxRadius)
    return circle
    
def onecircle(img,j,dr):
    k=0
    for i in data:
        k=k+1
        if(k>10):
            break
        cv.circle(image1,(i[0],i[1]),i[2],(0,255,0),2)
        print(i[0])
        print(i[1])
        cv.circle(image1,(i[0],i[1]),2,(0,0,255),3)
        cv.circle(image1,(i[0],i[1]),10,(0,0,255),3)
        if(k==j):#找到第几个圆然后进行保
            cut=image2[(i[1]-i[2]-5)*4:(i[1]+i[2]+5)*4,4*(i[0]-i[2]-5):(i[0]+i[2]+5)*4,:]
            
            cut1=cut.copy()

            cut=cv.Canny(cut,20,100)
    
            circles=cv.HoughCircles(cut,cv.HOUGH_GRADIENT,1,50,param1=1,param2=23,minRadius=30,maxRadius=300)

            circles=np.uint16(np.around(circles))
            data1=circles[0,]
    
            #Cir = findmaxRadius(cut,data1,20)
            Cir = findmaxRadius(cut,data1,dr)
            print('Cir:',Cir)
            Cir=list(Cir)

            out=FindPointsOnCircle(cut,Cir[0][0],Cir[0][1],Cir[0][2],3)

            C=cv.HoughCircles(out,cv.HOUGH_GRADIENT,1,60,param1=1,param2=13,minRadius=30,maxRadius=200)

            C=C[0,]
            cv.circle(cut1,(int(C[0][0]),int(C[0][1])),int(C[0][2]),(0,255,0),2)
            cv.circle(image2,(int(C[0][0]+4*(i[0]-i[2]-5)),int(C[0][1]+(i[1]-i[2]-5)*4)),int(C[0][2]),(0,255,0),2)
            center=(int(C[0][0]+4*(i[0]-i[2]-5)),int(C[0][1]+(i[1]-i[2]-5)*4))
            radial=C[0][2]
    return image2,center,radial






if __name__=='__main__':
    
    image=cv.imread("first.jpg")
    image2=image.copy()
    blockSize = 16#分成16块
    
    h,w=image.shape[0:2]
    print(h)
    print(w)
    image = cv.resize(image,(int(w/4),int(h/4)))

    image1=image.copy()

    image=cv.GaussianBlur(image,(5,5),3)
    
    image = unevenLightCompensate(image, blockSize)
    
    grayimage=rgb2gray(image)
    otsuimage=grayimage
    
    sobelimage=first_order(otsuimage)#一阶
    circles=cv.HoughCircles(sobelimage,cv.HOUGH_GRADIENT,1,50,param1=1,param2=56,minRadius=19,maxRadius=40)
    circles=np.uint16(np.around(circles))
    ##############################由于霍夫变换检测的圆是随机的故开始调整###################
    data=circles[0,]#所有圆的信息相关
    index=np.argsort(data,0)[:,1]
    
    data=data[index,:]
    data=nightcircle(data)
    
    #################################圆调整(从上到下从左到右)################
    image2,center,radial=onecircle(data, 4,20)
    cv.imshow('opop',image2)
    print('圆心坐标',center)
    print('半径',radial)
    cv.waitKey(0)
    cv.destroyAllWindows()
    

通过算法然后滤波得到
在这里插入图片描述选择的某一个圆消除噪点

最后效果
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值