Distinguish head of bolt and its thread
Hello. Im working on a project where i want to identify different kind of bolts. I made it so far that i can find the contours, place rectangs, and identify the reference (for the dimensions) in the picture. Because i am not interested in the head of the bolt, but only in the length and width of the threaded part, i need to remove the bold. De bolts can be placed in a random position, so i thought, take a crop of each bolt in the picture (there can be multiple bolts in 1 picture), rotate it so that its horizontal and count the pixels. But if you have other ideas i like to hear them. This method is a littly buggy if you ask me, but worth a try. Im not having succes cropping each bolt into a new image
Here what i got so far:
import numpy as np
import cv2
image = cv2.imread("knipsel5.jpg")
output = image.copy()
scalePercent = 100
width = int(image.shape[1] * scalePercent / 100)
height = int(image.shape[0] * scalePercent / 100)
dim = (width, height)
resizedImage = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)
blurred_image = cv2.GaussianBlur(resizedImage, (5,5), 0)
gray = cv2.cvtColor(blurred_image, cv2.COLOR_BGR2GRAY)
_, threshold = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY_INV)
font = cv2.FONT_HERSHEY_COMPLEX
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, 100)
if circles is not None:
circles = np.round(circles[0, :]).astype("int")
for(x,y,r) in circles:
cv2.circle(resizedImage, (x, y), r, (0, 255, 0), 4)
print("X coord:")
print(x)
print("Y coord:")
print(y)
print("Straal:")
print(r)
diameter = r*2
reference = 23/123
cv2.putText(resizedImage, ("coin "), ((x+100), (y-100)), font, 1, (0))
#cv2.putText(resizedImage, (r), ((x+120), (y-100)), font, 1, (0))
#cv2.imshow("output", np.hstack([image, resizedImage]))
circle = cv2.circle(threshold, (x,y), (r+50), (0,0,0), -1)
else:
print("no dimension reference found")
contours, hierarchy = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
height, width = threshold.shape
min_x, min_y = width, height
max_x = max_y = 0;
for cnt in contours:
approx = cv2.approxPolyDP(cnt, 0.005*cv2.arcLength(cnt, True), True)
cv2.drawContours(resizedImage, [approx] , 0, (255,0,0), 2)
(x,y,w,h) = cv2.boundingRect(approx)
min_x, max_x = min(x, min_x), max(x+w, max_x)
min_y, max_y = min(y, min_y), max(y+h, max_y)
if w > 40 and h > 40:
cv2.rectangle(resizedImage, (x,y), (x+w,y+h), (255, 0, 0), 2)
rect = cv2.minAreaRect(approx)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(resizedImage, [box],0,(0,0,255),2)
#rectangg = np.array([
# [[box[0][0], box[0][1]]],
# [[box[1][0], box[1][1]]],
# [[box[2][0], box[2][1]]],
# [[box[3][0], box[3][1]]],
# ])
lengte = int(rect[1][0])
breedte = int(rect[1][1])
print("x",x)
print("y",y)
print("w",w)
print("h",h)
print("approxlength")
print(len(approx))
print("boxLength")
print(box)
print("lengte: ", lengte)
print("breedte: ", breedte)
print("END")
print("")
x = approx.ravel()[0]
y = approx.ravel ...
since you already have a RotatedRect (nice !), you could use its angle property to warp it into a plain horizontal position. then maybe a simple absdiff with a resized template screw. or sum up along the y axis using reduce() to get a "spatial histogram" (along the x axis), easy to find the bolt then