我是openCV的新手,尝试将裁剪后的和未裁剪后的矩形的图像上的90度角合适(如图所示)
我尝试了2种不同的方法,但都失败了:
1:尝试在图像上拟合矩形的最大面积,并将矩形的坐标用作4个候选对象
import cv2
import numpy as np
import matplotlib.pyplot as plt
## Grayscale the image
im = cv2.imread('testImages/download.jpeg',cv2.IMREAD_GRAYSCALE)
## Adpative thresholding using Otsu
(thresh, im) = cv2.threshold(im, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
def auto_canny(image, sigma=0.33):
# compute the median of the single channel pixel intensities
v = np.median(image)
# apply automatic Canny edge detection using the computed median
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(image, lower, upper)
# return the edged image
return edged
im_edge = auto_canny(im)
_,contours,hierarchy=cv2.findContours(im_edge,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.intp(box)
cv2.drawContours(im_edge,[box],0,(0,0,255),2)
cv2.imwrite('download' +"_result.jpeg", im_edge)
问题:从boxPoints返回的点都不是正确的候选值
2:计算沿每一列和每一列的像素值的平均值。具有最大斜率(变化)的行和列是拐角的候选对象
import matplotlib.pyplot as plt
import cv2
import numpy as np
## Grayscale the image
im = cv2.imread('testImages/download5.jpeg',cv2.IMREAD_GRAYSCALE)
## Adpative thresholding using Otsu
(thresh, im) = cv2.threshold(im, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
## Blur image to filter noisy edges
im = cv2.GaussianBlur(im,(5,5),0)
## Custom processing to detect edges
row, col = im.shape[0] , im.shape[1]
def sumvalues(vec):
return (vec.sum())/len(vec)
summedX=[]
for i in range(row):
summedX.append(sumvalues(im[i,:]))
summedY = []
for j in range(col):
summedY.append(sumvalues(im[:,j]))
rowSummed = np.asarray(summedX)
colSummed = np.asarray(summedY)
## First order difference
xDiff_1 = np.diff(rowSummed)
xDiff_2 = np.diff(xDiff_1)
xCornerIndx = np.where(np.absolute(xDiff_1)==np.absolute(xDiff_1).max())
yDiff_1 = np.diff(colSummed)
yDiff_2 = np.diff(yDiff_1)
yCornerIndx = np.where(np.absolute(yDiff_1)==np.absolute(yDiff_1).max())
plt.subplot(2,1,1),plt.imshow(im,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
cv2.circle(im, (yCornerIndx[0],xCornerIndx[0]),10, (255, 0, 255), -1)
plt.subplot(2,1,2)
plt.plot(summedX,'b',label='rowSummed')
plt.plot(summedY,'g',label='colSummed')
plt.legend()
plt.show()
问题:虽然此过程适用于小角度的拐角,但此方法容易在边缘产生噪声,而对于大角度的拐角则失败