所以我实现了this答案中描述的解决方案,它在某些情况下有效,而在其他情况下则失败。在我看来,在某些情况下,两个或两个以上的聚类正在求和以确定一个角落,而不是每个角落只有一个聚类。
但是,以下这些图像存在群集平均问题:
当我尝试平均某些图像的群集时,我还会收到以下警告,然后出现程序崩溃:
C:\ Users \ ocheg \ OneDrive \ Desktop \ SpAM \ Solution1.py:52:RuntimeWarning:除以int_scalars中遇到的零 ((x1-x2)(y3-y4)-(y1-y2)(x3-x4)) C:\ Users \ ocheg \ OneDrive \ Desktop \ SpAM \ Solution1.py:54:RuntimeWarning:无效> int_scalars中遇到的值 ((x1-x2)(y3-y4)-(y1-y2)(x3-x4))
我的完整代码如下:
from PIL import Image
import numpy as np
import cv2
import glob
#import images from folder
images = [cv2.imread(file) for file in glob.glob("SpAMImages/*.jpg")]
for image in images:
#resize to make all images the same size, also makes display easier to work with
image = cv2.resize(image, (715,715))
#apply Gaussian blur
blur = cv2.GaussianBlur(image,(3,3),0)
#determines closing circle size. using 16 pixels
kernel = np.ones((7,7), np.uint8)
#converts image to grayscale
gray_img = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
#performs morphological closing
close_img = cv2.morphologyEx(gray_img, cv2.MORPH_CLOSE, kernel)
#applies Otsu thresholding
ret,threshold_img = cv2.threshold(close_img, 0, 255, cv2.THRESH_OTSU)
#closes holes with morphological closing
threshold_img = cv2.morphologyEx(threshold_img, cv2.MORPH_CLOSE, kernel)
#extract largest component from image.
components, output, stats, centroids = cv2.connectedComponentsWithStats(threshold_img, connectivity=4)
sizes = stats[:, -1]
max_label = 1
max_size = sizes[1]
for i in range(2, components):
if sizes[i] > max_size:
max_label = i
max_size = sizes[i]
biggestComponent = np.zeros(output.shape)
biggestComponent[output == max_label] = 255
biggestComponent = biggestComponent - cv2.erode(biggestComponent, np.ones((5,5), np.uint8))
dilated = cv2.dilate(biggestComponent, np.ones((3,3), dtype=np.uint8))
#--------------------- obtaining corners using houghlines--------------------#
def find_intersection(line1, line2):
# extract points
x1, y1, x2, y2 = line1[0]
x3, y3, x4, y4 = line2[0]
运行时警告在这里发生:
# compute determinant
Px = ((x1*y2 - y1*x2)*(x3-x4) - (x1-x2)*(x3*y4 - y3*x4))/ \
((x1-x2)*(y3-y4) - (y1-y2)*(x3-x4))
Py = ((x1*y2 - y1*x2)*(y3-y4) - (y1-y2)*(x3*y4 - y3*x4))/ \
((x1-x2)*(y3-y4) - (y1-y2)*(x3-x4))
return Px, Py
def segment_lines(lines, delta):
h_lines = []
v_lines = []
for line in lines:
for x1, y1, x2, y2 in line:
if abs(x2-x1) < delta: # x-values are near; line is vertical
v_lines.append(line)
elif abs(y2-y1) < delta: # y-values are near; line is horizontal
h_lines.append(line)
return h_lines, v_lines
def cluster_points(points, nclusters):
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
_, _, centers = cv2.kmeans(points, nclusters, None, criteria, 10, cv2.KMEANS_PP_CENTERS)
return centers
# run the Hough transform
lines = cv2.HoughLinesP(dilated.astype(np.uint8), rho=1, theta=np.pi/180, threshold=100, maxLineGap=50, minLineLength=150)
# segment the lines
delta = 180
h_lines, v_lines = segment_lines(lines, delta)
# draw the segmented lines
houghimg = image.copy()
for line in h_lines:
for x1, y1, x2, y2 in line:
color = [0,0,255] # color hoz lines red
cv2.line(houghimg, (x1, y1), (x2, y2), color=color, thickness=1)
for line in v_lines:
for x1, y1, x2, y2 in line:
color = [255,0,0] # color vert lines blue
cv2.line(houghimg, (x1, y1), (x2, y2), color=color, thickness=1)
# find the line intersection points
Px = []
Py = []
for h_line in h_lines:
for v_line in v_lines:
px, py = find_intersection(h_line, v_line)
Px.append(px)
Py.append(py)
# draw the intersection points
intersectsimg = image.copy()
for cx, cy in zip(Px, Py):
cx = np.round(cx).astype(int)
cy = np.round(cy).astype(int)
color = np.random.randint(0,255,3).tolist() # random colors
cv2.circle(intersectsimg, (cx, cy), radius=2, color=color, thickness=-1) # -1: filled circle
'''
# use clustering to find the centers of the data clusters
P = np.float32(np.column_stack((Px, Py)))
nclusters = 4
centers = cluster_points(P, nclusters)
#print(centers)
# draw the center of the clusters
for cx, cy in centers:
cx = np.round(cx).astype(int)
cy = np.round(cy).astype(int)
cv2.circle(image, (cx, cy), radius=4, color=[0,0,255], thickness=-1) # -1: filled circle
'''
'''
biggestComponent = np.float32(biggestComponent)
dst = cv2.cornerHarris(biggestComponent,2,3,0.04)
dst = cv2.dilate(dst,None)
dst = cv2.dilate(dst,None)
#threshold
image[dst>0.01*dst.max()]=[0,0,255]
'''
'''
cv2.namedWindow('threshold image', cv2.WINDOW_NORMAL)
cv2.resizeWindow('threshold image', 400, 400)
cv2.namedWindow('biggest component', cv2.WINDOW_NORMAL)
cv2.resizeWindow('biggest component', 400, 400)
cv2.namedWindow('close_img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('close_img', 400, 400)
cv2.namedWindow('hough', cv2.WINDOW_NORMAL)
cv2.resizeWindow('hough', 400, 400)
'''
cv2.namedWindow('intersection', cv2.WINDOW_NORMAL)
cv2.resizeWindow('intersection', 400, 400)
#cv2.imshow('threshold image', image)
#cv2.imshow('close_img', close_img)
#cv2.imshow('biggest component', biggestComponent)
#cv2.imshow('hough', houghimg)
cv2.imshow('intersection', intersectsimg)
cv2.waitKey(0)