openCV提取图像中的矩形区域


Posted in Python onJuly 21, 2020

改编自详解利用OpenCV提取图像中的矩形区域(PPT屏幕等) 原文是c++版,我改成了python版,供大家参考学习。
主要思想:边缘检测—》轮廓检测—》找出最大的面积的轮廓—》找出顶点—》投影变换

import numpy as np
import cv2
# 这个成功的扣下了ppt白板
srcPic = cv2.imread('2345.jpg')
length=srcPic.shape[0]
depth=srcPic.shape[1]
polyPic = srcPic
shrinkedPic = srcPic
greyPic = cv2.cvtColor(shrinkedPic, cv2.COLOR_BGR2GRAY)
ret, binPic = cv2.threshold(greyPic, 130, 255, cv2.THRESH_BINARY)
print(binPic.shape)
median = cv2.medianBlur(binPic, 5)
# 进行边缘检测
cannyPic = cv2.Canny(median, 10, 200)

cv2.namedWindow("binary", 0)
cv2.namedWindow("binary2", 0)
cv2.imshow("binary", cannyPic)
# 找出轮廓
contours, hierarchy = cv2.findContours(cannyPic, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
cv2.imwrite('binary2.png', cannyPic)
cv2.imshow("binary2", cannyPic)
i = 0
maxArea = 0
# 挨个检查看那个轮廓面积最大
for i in range(len(contours)):
 if cv2.contourArea(contours[i]) > cv2.contourArea(contours[maxArea]):
 maxArea = i
#检查轮廓得到分布在四个角上的点
hull = cv2.convexHull(contours[maxArea])
s = [[1,2]]
z = [[2,3]]
for i in hull:
 s.append([i[0][0],i[0][1]])
 z.append([i[0][0],i[0][1]])
del s[0]
del z[0]

#现在的目标是从一堆点中挑出分布在四个角落的点,决定把图片分为四等份,每个区域的角度来划分点,
#默认四个角分别分布在图像的四等分的区间上,也就是矩形在图像中央
# 我们把所有点的坐标,都减去图片中央的那个点(当成原点),然后按照x y坐标值的正负 判断属于哪一个区间

center=[length/2,depth/2]

# 可以得到小数
for i in range(len(s)):
 s[i][0] = s[i][0] - center[0]
 s[i][1] = s[i][1] - center[1]
one = []
two = []
three = []
four = []
# 判断是那个区间的
for i in range(len(z)):
 if s[i][0] <= 0 and s[i][1] <0 :
 one.append(i)
 elif s[i][0] > 0 and s[i][1] <0 :
 two.append(i)
 elif s[i][0] >= 0 and s[i][1] > 0:
 four.append(i)
 else:three.append(i)

p=[]
distance=0
temp = 0
# 下面开始判断每个区间的极值,要选择距离中心点最远的点,就是角点
for i in one :
 x=z[i][0]-center[0]
 y=z[i][1]-center[1]
 d=x*x+y*y
 if d > distance :
 temp = i
 distance = d
p.append([z[temp][0],z[temp][1]])
distance=0
temp=0
for i in two :
 x=z[i][0]-center[0]
 y=z[i][1]-center[1]
 d=x*x+y*y
 if d > distance :
 temp = i
 distance = d
p.append([z[temp][0],z[temp][1]])
distance=0
temp=0
for i in three :
 x=z[i][0]-center[0]
 y=z[i][1]-center[1]
 d=x*x+y*y
 if d > distance :
 temp = i
 distance = d
p.append([z[temp][0],z[temp][1]])
distance=0
temp=0
for i in four :
 x=z[i][0]-center[0]
 y=z[i][1]-center[1]
 d=x*x+y*y
 if d > distance :
 temp = i
 distance = d
p.append([z[temp][0],z[temp][1]])


for i in p:
 cv2.circle(polyPic, (i[0],i[1]),2,(0,255,0),2)
# 给四个点排一下顺序
a=[]
b=[]
st=[]
for i in p:
 a.append(i[0])
 b.append(i[1])
index=np.lexsort((b, a))
for i in index:
 st.append(p[i])
p = st
print(p)
pts1 = np.float32([[p[0][0],p[0][1]],[p[1][0],p[1][1]],[p[2][0],p[2][1]],[p[3][0],p[3][1]]])
# dst=np.float32([[0,0],[0,srcPic.shape[1]],[srcPic.shape[0],0],[srcPic.shape[0],srcPic.shape[1]]])
dst=np.float32([[0,0],[0,600],[400,0],[400,600]])

# 投影变换
M = cv2.getPerspectiveTransform(pts1,dst)
cv2.namedWindow("srcPic2", 0)
cv2.imshow("srcPic2", srcPic)
#dstImage = cv2.warpPerspective(srcPic,M,(srcPic.shape[0],srcPic.shape[1]))
dstImage = cv2.warpPerspective(srcPic,M,(400,600))


# 在原图上画出红色的检测痕迹,先生成一个黑色图
black = np.zeros((shrinkedPic.shape[0], shrinkedPic.shape[1]), dtype=np.uint8)
# 二值图转为三通道图
black3 = cv2.merge([black, black, black])
# black=black2
cv2.drawContours(black, contours, maxArea, 255, 11)
cv2.drawContours(black3, contours, maxArea, (255, 0, 0), 11)
cv2.imwrite('cv.png', black)

cv2.namedWindow("cannyPic", 0)
cv2.imshow("cannyPic", black)
cv2.namedWindow("shrinkedPic", 0)
cv2.imshow("shrinkedPic", polyPic)
cv2.namedWindow("dstImage", 0)
cv2.imshow("dstImage", dstImage)
# 等待一个按下键盘事件
cv2.waitKey(0)
# 销毁所有创建出的窗口

运行效果

openCV提取图像中的矩形区域

用到的图片

openCV提取图像中的矩形区域

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python解释执行原理分析
Aug 22 Python
Python中获取对象信息的方法
Apr 27 Python
在Python的Flask框架中构建Web表单的教程
Jun 04 Python
深入理解Python装饰器
Jul 27 Python
Python实现读取Properties配置文件的方法
Mar 29 Python
简单实现python数独游戏
Mar 30 Python
python 拷贝特定后缀名文件,并保留原始目录结构的实例
Apr 27 Python
python3.5安装python3-tk详解
Apr 26 Python
python3 requests库文件上传与下载实现详解
Aug 22 Python
Python绘制热力图示例
Sep 27 Python
pymysql 插入数据 转义处理方式
Mar 02 Python
Python开发五子棋小游戏
May 02 Python
Python文件夹批处理操作代码实例
Jul 21 #Python
Python常用库Numpy进行矩阵运算详解
Jul 21 #Python
python按顺序重命名文件并分类转移到各个文件夹中的实现代码
Jul 21 #Python
Pandas的Apply函数具体使用
Jul 21 #Python
Python pandas对excel的操作实现示例
Jul 21 #Python
浅谈Python爬虫原理与数据抓取
Jul 21 #Python
用于ETL的Python数据转换工具详解
Jul 21 #Python
You might like
php 修改、增加xml结点属性的实现代码
2013/10/22 PHP
php用header函数实现301跳转代码实例
2013/11/25 PHP
分享PHP-pcntl 实现多进程代码
2016/09/30 PHP
php操作redis命令及代码实例大全
2020/11/19 PHP
刷新页面实现方式总结(HTML,ASP,JS)
2008/11/13 Javascript
JavaScript 的方法重载效果
2009/08/07 Javascript
javascript预览上传图片发现的问题的解决方法
2010/11/25 Javascript
JQuery datepicker 使用方法
2011/05/20 Javascript
window.print打印指定div实例代码
2013/12/13 Javascript
javascript得到当前页的来路即前一页地址的方法
2014/02/18 Javascript
使用原生js写的一个简单slider
2014/04/29 Javascript
node.js中的path.join方法使用说明
2014/12/08 Javascript
jQuery中的编程范式详解
2014/12/15 Javascript
微信支付如何实现内置浏览器的H5页面支付
2015/09/25 Javascript
EasyUI布局 高度自适应
2016/06/04 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
2016/06/13 Javascript
手机Web APP如何实现分享多平台功能
2016/08/19 Javascript
JS实现禁止高频率连续点击的方法【基于ES6语法】
2017/04/25 Javascript
jQuery实现页码跳转式动态数据分页
2017/12/31 jQuery
JavaScript模板引擎原理与用法详解
2018/12/24 Javascript
JavaScript对JSON数组简单排序操作示例
2019/01/31 Javascript
JS将时间秒转换成天小时分钟秒的字符串
2019/07/10 Javascript
JavaScript中的this基本问题实例小结
2020/03/09 Javascript
vue-cli3单页构建大型项目方案
2020/04/07 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
2020/05/30 jQuery
Python可跨平台实现获取按键的方法
2015/03/05 Python
Python使用scipy模块实现一维卷积运算示例
2019/09/05 Python
django中嵌套的try-except实例
2020/05/21 Python
人力资源总监工作说明
2014/03/03 职场文书
2014年元旦感言
2014/03/06 职场文书
快餐公司创业计划书
2014/04/29 职场文书
环保倡议书400字
2014/05/15 职场文书
班级学习雷锋活动总结
2014/07/04 职场文书
2014年党员整改措施范文
2014/09/21 职场文书
2015年餐厅服务员工作总结
2015/04/23 职场文书
食品安全责任书范本
2015/05/09 职场文书