题目:给定一组啮合的齿轮图像,计算该组齿轮的所有参数
一、二值化
1 import cv2 2 import numpy as np 3 import matplotlib.pyplot as plt 4 5 plt.rcParams[‘font.sans-serif‘]=[‘SimHei‘] 6 plt.rcParams[‘axes.unicode_minus‘]=False 7 8 gears = cv2.imread(‘gears.bmp‘,0) 9 ‘‘‘对图像进行阈值分割‘‘‘ 10 thres, Out1 = cv2.threshold(gears, 0, 255, cv2.THRESH_OTSU) #大津阈值分割 11 cv2.imwrite(f‘gears_binary(阈值={thres}).bmp‘, Out1) 12 plt.subplot(111), plt.imshow(Out1,‘gray‘), plt.title(f‘阈值 = {thres}‘), plt.show()
二、通过判断极坐标变化后是否为直线来确定圆心坐标
1 def get_center(): 2 ‘‘‘得到齿轮圆的中心‘‘‘ 3 def true_line(polar_img): 4 ‘‘‘判断纵向是否为一条直线‘‘‘ 5 lengths = [] 6 for row in range(50, 300): 7 line = polar_img[row, ...] 8 len2first_255 = list(line).index(255) 9 lengths.append(len2first_255) 10 d_value = np.ptp(lengths) 11 print(d_value) 12 if d_value < 4: #设置阈值4 13 return True 14 else: 15 return False 16 17 centers = [] #记录圆心位置 18 ‘‘‘在给定的大致区域内扫描‘‘‘ 19 for rows in range(225, 230): 20 for cols in range(190, 195): 21 result = cv2.logPolar(Out1, (cols, rows), 110, cv2.WARP_FILL_OUTLIERS) 22 if true_line(result): 23 centers.append((rows,cols)) # col = x, row = y 24 for rows in range(225, 230): 25 for cols in range(468, 473): 26 result = cv2.logPolar(Out1, (cols, rows), 70, cv2.WARP_FILL_OUTLIERS) 27 if true_line(result): 28 centers.append((rows,cols)) 29 30 return centers 31 32 center = get_center() #得到大齿轮圆心为(col=191, row=228), 小齿轮圆心(470, 226)
三、极坐标变换
‘‘‘以大齿轮圆心为中心做极坐标变换‘‘‘ Polar_img = cv2.logPolar(Out1, (191, 228), 110, cv2.WARP_FILL_OUTLIERS) #参数110影响水平轴ρ与原图像宽度col单位的比值 cv2.imwrite(‘gears_Polar.bmp‘, Polar_img) plt.subplot(111), plt.imshow(Polar_img, ‘gray‘), plt.show()
四、取变换后图像齿形中间连续部分片段,通过傅里叶变换得到频率
1 ‘‘‘取变换后图像齿形中间连续部分片段,通过傅里叶变换得到频率‘‘‘ 2 def get_curve(polar_img): 3 ‘‘‘取齿形‘‘‘ 4 lengths = [] 5 for row in range(150, 300): # 截取长度为150的齿形 6 for col in range(polar_img.shape[1]-1, 300, -1): 7 if polar_img[row, col] == 255: 8 lengths.append(col) 9 break 10 return lengths 11 12 def get_Frequence(polar_img): 13 ‘‘‘计算频率‘‘‘ 14 y = get_curve(polar_img) 15 y = y - np.mean(y) 16 Fourier = np.fft.fft(y) 17 A = np.abs(Fourier) 18 x = [i for i in range(0, 75) ] 19 plt.plot(x, A[:75]), plt.savefig(‘傅里叶幅值图‘) 20 return list(A[:75]).index(max(A[:75]))/150 21 22 Fs = get_Frequence(Polar_img) 23 print(f‘齿形的频率为:{Fs}‘) 24 gear_num = Fs * Polar_img.shape[0] #根据频率计算齿数 25 print(f‘大齿轮齿数为:{gear_num}‘)
五、计算大齿轮直径和其他齿轮参数
1 def get_D(): 2 ‘‘‘求大齿轮齿顶圆直径‘‘‘ 3 def get_maxR(out1_img, row_range): 4 ‘‘‘计算给定齿形片段到圆心的最大距离‘‘‘ 5 distances = [] 6 for row in range(row_range[0], row_range[1]): 7 for col in range(70): 8 if out1_img[row, col] == 255: 9 distance = np.sqrt( (228-row)**2 + (191-col)**2 ) 10 distances.append(distance) 11 break 12 return max(distances) 13 R1 = get_maxR(Out1, (150, 200)) 14 R2 = get_maxR(Out1, (200, 250)) 15 R3 = get_maxR(Out1, (250, 300)) 16 R_1 = (R1+R2+R3)/3 #取三个最大距离的平均值 17 return R_1 * 2 18 19 Da = get_D() # 得到大齿轮齿顶圆直径为 351.324 20 print(f‘大齿轮齿顶圆直径为:{Df}‘) 21 mod_num = Da/(gear_num + 2) #计算模数 22 print(f‘模数 = {mod_num}‘) 23 D = gear_num * mod_num 24 print(f‘大齿轮分度圆直径 = {D}‘) 25 Dj = D * np.cos(np.deg2rad(20)) 26 print(f‘大齿轮基圆直径 = {Dj}‘)
1 center_distance = np.sqrt((470-191)**2 + (226-228)**2) # 计算中心距 2 print(f‘中心距 = {center_distance}‘) 3 4 D2 = (center_distance - D/2) * 2 5 gear2_num = round(gear_num * D2/D) 6 Dj2 = D2 * np.cos(np.deg2rad(20)) 7 print(f‘小齿轮齿数 = {gear2_num},分度圆直径 = {D2},基圆直径 = {Dj2}‘) 8 9 gear_d = np.pi * mod_num 10 print(f‘齿距 = {gear_d},齿厚 = 齿槽距 = {gear_d/2}‘) 11 ha = 1 * mod_num 12 hf = 1.25 * mod_num 13 h = ha + hf 14 print(f‘齿顶高 = {ha},齿根高 = {hf},齿高 = {h}‘)
原文:https://www.cnblogs.com/Pio-GD/p/14223942.html