python - 水印opencv周围的轮廓
问题描述
我想在图像中的水印周围画一个框。我已经提取了水印并找到了轮廓。然而,轮廓不是围绕水印绘制的。轮廓是在我的完整图像上绘制的。请帮助我正确的代码。
轮廓坐标的输出为:
[array([[[ 0, 0]],
[[ 0, 634]],
[[450, 634]],
[[450, 0]]], dtype=int32)]
输出图像为:
我的代码片段如下:
img = cv2.imread('Watermark/w3.png')
gr = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
bg = gr.copy()
closing = cv2.morphologyEx(bg, cv2.MORPH_CLOSE, kernel) #dilation followed by erosion
#plt.imshow(cv2.subtract(img,opening))
plt.imshow(closing)
_,contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(contours)
print(len(contours))
if len(contours)>0 :
cnt=contours[len(contours)-1]
cv2.drawContours(closing, [cnt], 0, (0,255,0), 3)
plt.imshow(closing)
解决方案
该函数findContours
难以找到您的框轮廓,因为预计会在二进制图像上运行。从文档中:
为了获得更好的准确性,请使用二值图像。所以在寻找轮廓之前,应用阈值或精确边缘检测。
在 OpenCV 中,寻找轮廓就像从黑色背景中寻找白色物体。所以请记住,要找到的对象应该是白色的,背景应该是黑色的。
因此,在cvtColor
应用功能后threshold
确保您有黑色背景。
...
img = cv2.imread('sample.png')
gr = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, bg = cv2.threshold(gr, 127, 255, cv2.THRESH_BINARY_INV)
...
如果你findContours
在这个二进制图像上运行,你会发现多个框
要在整个文本周围获得一个框,您可以在创建单个 blobiterations
的函数上搜索参数
的数量。morphologyEx
...
kernel = np.ones((3,3))
closing = cv2.morphologyEx(bg, cv2.MORPH_CLOSE, kernel, iterations=5)
...
因此,在创建 blob 后,应用findContours
您已经拥有的并使用minAreaRect找到旋转的矩形,其最小面积包含所传递的点集。
...
contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(len(contours))
for i in range(len(contours)):
rect = cv2.minAreaRect(contours[i])
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img,[box],0,(127,60,255),2)
cv2.imwrite("output_box.png", img)
推荐阅读
- ruby-on-rails - 帽子流产了!SSHKit::Runner::ExecuteError:在主机 xxx.xxx.xx.xx 上执行时出现异常:部署程序
- javascript - JS调用的Flask多个变量
- javascript - 如何将 .then .catch 转换为 async/await
- java - 位置更新提供用于计算距离的随机数
- variables - 将 4 维变量转换为 3 维变量 netcdf
- r - Colsums使用r中列表中索引的循环
- javascript - 打字稿承诺导致代码静默崩溃
- c - GetMessageW 正在阻塞调用线程,没有收到任何消息
- c++ - 使用 memcpy 从二维数组中复制一系列元素
- r - 无法为 R 中的列表替换 NA 的错字