简体   繁体   English

计数齿轮(Python,OpenCV)

[英]Count gear (Python, OpenCV)

For a prototype I need to build a 3d model of a gear. 对于原型,我需要构建齿轮的3D模型。 This have a "many" number of teeth. 这有很多齿。 So I am trying to count them using OpenCV and Python. 因此,我尝试使用OpenCV和Python计算它们的数量。 I found this (only?) post which explain how to do it in C++. 我发现了这篇 (仅?)帖子,它解释了如何在C ++中做到这一点。

I am following the steps and, for now this is the code I made. 我正在按照步骤进行操作,现在这是我编写的代码。

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)

What stopped me from go ahead is this: the image at some point became really a mess. 阻止我前进的原因是:在某些时候,图像确实变得一团糟。

This is the original on which I am working: 这是我正在处理的原始文件:

SRC

And this is the output of image_dilate 这是image_dilate的输出

O1

As you can see, the teeth at the bottom is not displayed properly, maybe because of the shaddow in the original image. 如您所见,底部的牙齿未正确显示,可能是由于原始图像中的阴影所致。 How can I get rid of this ? 我该如何摆脱呢?

Because your source image is cleaner than the link your post, so you can do approx on the max-area-contour , then get half number of points , the result is 84 . 因为您的源图像比帖子的链接更干净 ,所以您可以对max-area-contour进行近似处理 ,然后获得一半的点数 ,结果为84

在此处输入图片说明


Sample code: 样例代码:

#!/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()

Result: 结果:

在此处输入图片说明

Solved it.. 解决了..

This is the code. 这是代码。 The count is wrong by one because one teeth, on the right is lower than the others and because it found two points by itself. 一个人的计数是错误的,因为右边的一颗牙齿比另外一颗低,并且它自己发现了两点。 Don't know why this happens. 不知道为什么会这样。

Also, it has been made with another image. 另外,它是用另一个图像制作的。 It's not the source I posted above as long as it is in low definition. 只要它是低清晰度,它都不是我在上面发布的来源。

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)

产量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM