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程序设计入门(4)模块和包
Jun 16 Python
简单讲解Python中的闭包
Aug 11 Python
浅谈python中的面向对象和类的基本语法
Jun 13 Python
python清理子进程机制剖析
Nov 23 Python
python3库numpy数组属性的查看方法
Apr 17 Python
python操作excel的包(openpyxl、xlsxwriter)
Jun 11 Python
python逆序打印各位数字的方法
Jun 25 Python
python Flask 装饰器顺序问题解决
Aug 08 Python
python 实现将txt文件多行合并为一行并将中间的空格去掉方法
Dec 20 Python
使用Python爬虫库requests发送表单数据和JSON数据
Jan 25 Python
spyder 在控制台(console)执行python文件,debug python程序方式
Apr 20 Python
celery在python爬虫中定时操作实例讲解
Nov 27 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 删除数组元素
2009/01/16 PHP
php压缩HTML函数轻松实现压缩html/js/Css及注意事项
2013/01/27 PHP
php mail to 配置详解
2014/01/16 PHP
PHP微信红包API接口
2015/12/05 PHP
php如何控制用户对图片的访问 PHP禁止图片盗链
2016/03/25 PHP
php+ajax简单实现全选删除的方法
2016/12/06 PHP
php在linux环境中如何使用redis详解
2020/12/15 PHP
单击复制文字兼容各浏览器的完美解决方案
2013/07/04 Javascript
jquery中加载图片自适应大小主要实现代码
2013/08/23 Javascript
JavaScript中string转换成number介绍
2014/12/31 Javascript
BootStrap中Datetimepicker和uploadify插件应用实例小结
2016/05/26 Javascript
使用jQuery.Qrcode插件在客户端动态生成二维码并添加自定义Logo
2016/09/01 Javascript
微信小程序 使用canvas制作K线实例详解
2017/01/12 Javascript
详解angularjs中的隔离作用域理解以及绑定策略
2017/05/31 Javascript
小发现之浅谈location.search与location.hash的问题
2017/06/23 Javascript
详解在 Angular 项目中添加 clean-blog 模板
2017/07/04 Javascript
weex里Vuex state使用storage持久化详解
2017/09/09 Javascript
vue之父子组件间通信实例讲解(props、$ref、$emit)
2018/05/22 Javascript
angular 实现的输入框数字千分位及保留几位小数点功能示例
2018/06/19 Javascript
angular 数据绑定之[]和{{}}的区别
2018/09/25 Javascript
Vue2.x中利用@font-size引入字体图标报错的解决方法
2018/09/28 Javascript
JavaScript算法学习之冒泡排序和选择排序
2019/11/02 Javascript
vue-cli创建的项目中的gitHooks原理解析
2020/02/14 Javascript
python中实现定制类的特殊方法总结
2014/09/28 Python
python简单程序读取串口信息的方法
2015/03/13 Python
对numpy中二进制格式的数据存储与读取方法详解
2018/11/01 Python
解决Python中定时任务线程无法自动退出的问题
2019/02/18 Python
使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件及出现问题解决方法
2019/09/06 Python
Python实现分数序列求和
2020/02/25 Python
python名片管理系统开发
2020/06/18 Python
matplotlib交互式数据光标实现(mplcursors)
2021/01/13 Python
Lookfantastic意大利官网:英国知名美妆购物网站
2019/05/31 全球购物
名词解释WEB SERVICE,SOAP,UDDI,WSDL,JAXP,JAXM;JSWDL开发包的介绍。
2012/10/27 面试题
如何转换一个字符串到enum值
2014/04/12 面试题
企业法人代表证明书
2015/06/18 职场文书
Win11 Build 22000.51版本文件资源管理器“命令栏”和上下文菜单有什么新变化?
2021/11/21 数码科技