簡體   English   中英

查找輪廓和邊界以獲取圖像 OpenCV Python 內的點

[英]Find contour and boundary to obtain points inside image OpenCV Python

我有一個代碼可以在圖像中繪制對象的輪廓,然后在它們周圍繪制一個矩形。 我需要找到我的形狀中最寬的直徑(兩點)女巫是水平直線 現在我需要找到對象邊界內的點(像素的坐標)。

繼承人我的代碼:

圖片供參考

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")

您可以嘗試找到極值點(在您的情況下為左、右和上)。 然后,您可以使用計算兩點之間的距離的公式 d=sqrt((x2-x1)^2 + (y2-y1)^2) 計算從最左邊到最右邊的距離。 如果您願意,您甚至可以找到線的中心並計算線的中心和極端頂點之間的距離。 這是一個示例代碼:

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)

結果:

在此處輸入圖片說明

您可以通過以下方式找到輪廓中的四個極值點:

首先,找到給定圖像的輪廓。 我為這個插圖考慮了以下圖像:

在此處輸入圖片說明

(跳過輪廓查找部分)

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM