2 回答

TA貢獻(xiàn)1921條經(jīng)驗(yàn) 獲得超9個贊
1 - 你將不得不對邊界做出一些假設(shè),如果它們存在 - 比如說它們不應(yīng)該超過 20 像素或者說圖像高度/寬度的 10%。查看您的數(shù)據(jù),您將能夠做出這個假設(shè)
現(xiàn)在我們將從圖像中分離出這 20 像素的邊界區(qū)域,并只在其中工作。
2 - 由于您的邊框顏色不同,因此將圖像轉(zhuǎn)換為灰度。在灰度上工作將使生活變得輕松。如果你能把它關(guān)起來,那就更好了。
import cv2 import numpy as np img = cv2.imread('input.png', 0) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
3 - 由于您的圖像邊界可能會被符號部分打斷 - 使用膨脹操作。如果存在統(tǒng)一邊界或不存在邊界 - 什么都不會發(fā)生。如果邊界存在并被中斷 - 擴(kuò)張操作將使它統(tǒng)一。
以大小為5的矩陣為核
kernel = np.ones((5,5), np.uint8) img_dilated = cv2.dilate(gray, kernel, iterations=1)
您將需要嘗試
內(nèi)核大小
迭代次數(shù)
膨脹后是否需要腐蝕操作。侵蝕與膨脹相反
4 - 現(xiàn)在讓我們使用拉普拉斯算子找出是否存在任何邊界。拉普拉斯算子是圖像二階空間導(dǎo)數(shù)的二維各向同性度量。圖像的拉普拉斯算子突出了快速強(qiáng)度變化的區(qū)域,因此經(jīng)常用于邊緣檢測。
laplacian = cv2.Laplacian(img_dilated,cv2.CV_64F)
在你的圖像的拉普拉斯算子中,你會看到兩條線代替你的邊界。注意 - 您不需要使用單獨(dú)的水平和垂直 sobel 運(yùn)算符。拉普拉斯算子同時處理水平和垂直。拉普拉斯算子是二階導(dǎo)數(shù),而索貝爾是一階導(dǎo)數(shù)。
5 - 現(xiàn)在您希望算法檢測是否有任何雙線。為此,我們使用霍夫變換。
# This returns an array of r and theta values
lines = cv2.HoughLines(edges,1,np.pi/180, 200)
# The below for loop runs till r and theta values
# are in the range of the 2d array
for r,theta in lines[0]:
# Stores the value of cos(theta) in a
a = np.cos(theta)
# Stores the value of sin(theta) in b
b = np.sin(theta)
6 - 如果 Hough 變換檢測到線條(檢查上面的角度 theta 與具有一定公差的期望) - 這意味著你的邊界存在。從圖像中刪除 20 像素的邊框。
注意- 這只是讓您入門的偽代碼。現(xiàn)實(shí)世界的問題需要大量的定制工作和實(shí)驗(yàn)。

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超4個贊
我設(shè)法找到了一種對我有用的方法,盡管如果圖像中有其他水平和垂直形狀則它不起作用。
我使用的想法是簡單地從邊框是水平和垂直形狀的假設(shè)開始,并從這些僅存在于邊框中的假設(shè)出發(fā)(意味著圖像本身沒有垂直或水平線,這是一種拉伸,但我的用例有那個假設(shè))。
這是我使用的代碼:
# extract horizontal and vertical lines
only_box = extract_all_squares(box, kernel_length=7)
# build up a mask of the same size as the image
mask = np.zeros(box.shape, dtype='uint8')
# get contours of horizontal and vetical lines
contours, hierarchy = cv2.findContours(only_box, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# draw contours on mask
mask = cv2.drawContours(mask, contours, -1, (255, 255, 255), thickness=cv2.FILLED)
# threhold mask and image
ret, mask = cv2.threshold(mask, 20, 255, cv2.THRESH_BINARY)
ret, box = cv2.threshold(box, 20, 255, cv2.THRESH_BINARY)
# remove the bits we don't want
box[mask == 0] = 255
具有以下輔助功能
def extract_all_squares(image, kernel_length):
"""
Binarizes image, keeping only vertical and horizontal lines
hopefully, it'll help us detect squares
Args:
image: image (cropped around circonstances)
kernel_length: length of kernel to use. Too long and you will catch everything,
too short and you catch nothing
Returns:
image binarized and keeping only vertical and horizozntal lines
"""
# thresholds image : anything beneath a certain value is set to zero
(thresh, img_bin) = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
# A vertical kernel of (1 X kernel_length), which will detect all the verticle lines from the image.
vertical_ksize = (1, kernel_length)
# Morphological operation to detect vertical lines from an image
verticle_lines_img = extract_lines(img_bin, vertical_ksize)
# A horizontal kernel of (kernel_length X 1), which will help to detect all the horizontal line from the image.
horizontal_ksize = (kernel_length, 1)
# Morphological operation to detect horizontal lines from an image
horizontal_lines_img = extract_lines(img_bin, horizontal_ksize)
img_final_bin = add_lines_together(verticle_lines_img, horizontal_lines_img)
return img_final_bin
def extract_lines(image, ksize):
"""
extract lines (horizontal or vertical, depending on ksize)
Args:
image: binarized image
ksize: size of kernel to use. Possible values :
horizontal_ksize = (kernel_length, 1)
vertical_ksize = (1, kernel_length)
Returns:
lines from image (vertical or horizontal, depending on ksize)
"""
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, ksize)
img_temp = cv2.erode(image, kernel, iterations=3)
lines_img = cv2.dilate(img_temp, kernel, iterations=3)
return lines_img
def add_lines_together(verticle_lines_img, horizontal_lines_img, alpha=0.5, beta=0.5):
"""
extract lines (horizontal or vertical, depending on ksize)
Args:
verticle_lines_img: image with vertical lines
horizontal_lines_img: image with horizontal lines
alpha : weight of first image. Keep at 0.5 for balance
beta : weight of second image. Keep at 0.5 for balance
alpha and beta are weighting parameters, this will
decide the quantity of an image to be added to make a new image
Returns:
image with an addition of both vertical and horizontal lines
"""
# This function helps to add two image with specific weight parameter to get a third image as summation of two image.
img_final_bin = cv2.addWeighted(verticle_lines_img, alpha, horizontal_lines_img, beta, 0.0)
# A kernel of (3 X 3) nes.
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# erodes boundaries of features, gets rid of some noise
img_final_bin = cv2.erode(~img_final_bin, kernel, iterations=2)
# further kill noise by thresholding
(thresh, img_final_bin) = cv2.threshold(img_final_bin, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
return img_final_bin
添加回答
舉報