[英]Find contour and boundary to obtain points inside image OpenCV Python
I have a code to draw contour of object in a image and then draw a rectangle around them.我有一个代码可以在图像中绘制对象的轮廓,然后在它们周围绘制一个矩形。 i need to find widest diameter in my shape (two point) witch is straight horizontal line Now I need to find the points(coordinates of the pixels) that are inside the boundary of the object.
我需要找到我的形状中最宽的直径(两点)女巫是水平直线 现在我需要找到对象边界内的点(像素的坐标)。
heres my code:继承人我的代码:
class App:
def __init__(self, window, window_title, image_path="ex.jpg"):
self.window = window
self.window.title(window_title)
# Load an image using OpenCV
self.cv_img = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB)
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
self.height, self.width, no_channels = self.cv_img.shape
# Create a canvas that can fit the above image
self.canvas = tkinter.Canvas(window, width = self.width, height = self.height)
self.canvas.pack()
# Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(self.cv_img))
# Add a PhotoImage to the Canvas
self.canvas.create_image(0, 0, image=self.photo, anchor=tkinter.NW)
# Button that lets the user blur the image
self.btn_blur=tkinter.Button(window, text="Blur", width=25, command=self.blur_image)
self.btn_blur.pack(anchor=tkinter.CENTER, expand=True)
# Button that lets the user edeged the image
self.btn_blur=tkinter.Button(window, text="edged", width=25, command=self.edged_image)
self.btn_blur.pack(anchor=tkinter.CENTER, expand=True)
# Button that lets the user edeged the image
self.btn_blur=tkinter.Button(window, text="draw box", width=25, command=self.draw_box)
self.btn_blur.pack(anchor=tkinter.CENTER, expand=True)
self.window.mainloop()
# Callback for the "Blur" button
def blur_image(self):
self.cv_img = cv2.blur(self.cv_img, (3, 3))
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(self.cv_img))
self.canvas.create_image(0, 0, image=self.photo, anchor=tkinter.NW)
# Callback for the "edged" button
def edged_image(self):
#edeged image
self.cv_img=cv2.Canny(self.cv_img,50,180)
self.cv_img = cv2.dilate(self.cv_img, None, iterations=1)
self.cv_img = cv2.erode(self.cv_img, None, iterations=1)
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(self.cv_img))
self.canvas.create_image(0, 0, image=self.photo, anchor=tkinter.NW)
# Callback for the "draw contours" button
def draw_box(self):
#draw contour
cnts = cv2.findContours(self.cv_img.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
#draw box
for c in cnts:
self.cv_img = cv2.drawContours(self.cv_img, [c], 0, (0,255,0), 3)
x,y,w,h = cv2.boundingRect(c)
self.cv_img = cv2.rectangle(self.cv_img,(x,y),(x+w,y+h),(0,255,0),2)
#Create a window and pass it to the Application object
App(tkinter.Tk(), "morteza app")
You can try to find extreme points (left, right, and top in your case).您可以尝试找到极值点(在您的情况下为左、右和上)。 You can then calculate the distance from extreme left to extreme right with the formula for calculating distance between two points d=sqrt((x2-x1)^2 + (y2-y1)^2).
然后,您可以使用计算两点之间的距离的公式 d=sqrt((x2-x1)^2 + (y2-y1)^2) 计算从最左边到最右边的距离。 You can even find the center of the line and calculate the distance between the center of the line and extreme top point if you would like with the same principle.
如果您愿意,您甚至可以找到线的中心并计算线的中心和极端顶点之间的距离。 Here is an example code:
这是一个示例代码:
import numpy as np
import cv2
import imutils
img = cv2.imread('bulb.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY)
cv2.bitwise_not(thresh, thresh)
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0]
c = max(cnts, key=cv2.contourArea)
left = tuple(c[c[:, :, 0].argmin()][0])
right = tuple(c[c[:, :, 0].argmax()][0])
distance = np.sqrt( (right[0] - left[0])**2 + (right[1] - left[1])**2 )
x,y,w,h = cv2.boundingRect(c)
centx = np.sqrt( ((right[0] + left[0])**2)/4)
centy = np.sqrt( ((right[1] + left[1])**2)/4 )
print(centx, centy)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.circle(img, left, 5, (0, 0, 255), -1)
cv2.circle(img, right, 5, (0, 0, 255), -1)
cv2.circle(img, (int(centx), int(centy)), 5, (0, 0, 255), -1)
cv2.line(img, left, right, (255,0,0), 2)
cv2.drawContours(img, [c], -1, (0,255,0), 2)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.putText(img,'Distance: '+str(distance),(10,30), font, 1, (0,0,0),2, cv2.LINE_AA)
cv2.imshow('img', img)
cv2.imwrite('bulbresult.png', img)
Result:结果:
You can find the four extreme points in a contour the following way:您可以通过以下方式找到轮廓中的四个极值点:
First, finding contours for a given image.首先,找到给定图像的轮廓。 I considered the following image for this illustration:
我为这个插图考虑了以下图像:
(Skipping the contour finding section) (跳过轮廓查找部分)
cnt = contours[0] #--- since there is only one contour in the image
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
#--- drawing these points on the image ----
cv2.circle(im2, leftmost, 6, (0, 0, 255), -1)
cv2.circle(im2, rightmost, 6, (0, 0, 255), -1)
cv2.circle(im2, topmost, 6, (0, 255, 0), -1)
cv2.circle(im2, bottommost, 6, (0, 255, 0), -1)
cv2.imshow('final', im2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.