计数齿轮(Python,OpenCV)

时间:2018-01-21 20:07:22

标签: python opencv

对于原型,我需要建立一个齿轮的三维模型。这有很多"很多"牙齿数量。 所以我试图用OpenCV和Python来计算它们。我发现this(仅?)帖子解释了如何在C ++中完成它。

我正在遵循这些步骤,现在这是我制作的代码。

import numpy as np
import cv2

img = cv2.imread('C:\\Users\\Link\\Desktop\\gear.png')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)

kernel = np.ones((3, 3), np.uint8)

img_erosion = cv2.erode(thresh, kernel, iterations=1)

edges = cv2.Canny(img_erosion, 50, 150)

img_dilate = cv2.dilate(edges, kernel, iterations=1)

cv2.imshow('i', thresh)
cv2.waitKey(0)
cv2.imshow('i', img_erosion)
cv2.waitKey(0)
cv2.imshow('i', edges)
cv2.waitKey(0)
cv2.imshow('i', img_dilate)
cv2.waitKey(0)

阻止我继续前进的是:在某些时候,图像变得一团糟。

这是我正在工作的原件:

src

这是image_dilate

的输出

o1

如您所见,底部的牙齿显示不正确,可能是因为原始图像中的阴影。我怎么能摆脱这个?

2 个答案:

答案 0 :(得分:1)

因为你的源图片更清洁比你帖子的链接所以你可以做近似最大面积轮廓,然后得到一半的积分,结果为 #!/usr/bin/python3 # 2018.01.22 11:53:24 CST import cv2 import myutils ## Read img = cv2.imread("img13_2.jpg") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ## threshold and find contours ret, threshed = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY_INV) cnts= cv2.findContours(threshed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] ## Find the max-area-contour cnt = max(contours, key=cv2.contourArea) ## Approx the contour arclen = cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, 0.002*arclen, True) ## Draw and output the result for pt in approx: cv2.circle(img, (pt[0][0],pt[0][1]), 3, (0,255,0), -1, cv2.LINE_AA) msg = "Total: {}".format(len(approx)//2) cv2.putText(img, msg, (20,40),cv2.FONT_HERSHEY_PLAIN, 2, (0,0,255), 2, cv2.LINE_AA) ## Display cv2.imshow("res", img);cv2.waitKey()

enter image description here

示例代码:

# :query need to be an array
# Eg:
# "Product name 1, Product name 2, Product name 3" =>  params[:q].split(', ')
# => ["Product name 1", "Product name 3", "Product name 3"]

search_string = []
query.each { |q| search_string << "name ILIKE ?" }
search_string = search_string.join(' OR ')

Product.where(search_string, *query)

结果:

enter image description here

答案 1 :(得分:0)

解决了它..

这是代码。计数是错误的,因为右边的一颗牙齿低于其他牙齿,因为它自己发现了两个点。不知道为什么会这样。

此外,它是用另一张图片制作的。只要它处于低清晰度,它就不是我在上面发布的来源。

import numpy as np
import cv2

img = cv2.imread('C:\\Users\\Link\\Desktop\\gear.png')
img2 = cv2.imread('C:\\Users\\Link\\Desktop\\gear.png')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)

kernel = np.ones((3, 3), np.uint8)

img_dilate = cv2.dilate(thresh, kernel, iterations=1)

im2, contours, hierarchy = cv2.findContours(img_dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cv2.drawContours(img, contours, -1, (0, 255, 0), -1)

edges = cv2.Canny(cnts, 350, 350)

cnt = contours[0]

hull = cv2.convexHull(cnt, returnPoints=False)
defects = cv2.convexityDefects(cnt, hull)

for i in range(defects.shape[0]):
    s, e, f, d = defects[i, 0]
    start = tuple(cnt[s][0])
    end = tuple(cnt[e][0])
    far = tuple(cnt[f][0])
    cv2.line(edges, start, end, [0, 255, 255], 1)
    circles = cv2.circle(img2, end, 5, [0, 255, 0], -1)


# print(len(defects)) - number of points

cv2.imshow('thresh', thresh)
cv2.waitKey(0)
cv2.imshow('dilate', img_dilate)
cv2.waitKey(0)
cv2.imshow('edges', edges)
cv2.waitKey(0)
cv2.imshow('cnts', cnts)
cv2.waitKey(0)
cv2.imshow('points', circles)
cv2.waitKey(0)

output