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实现随机密码字典生成器示例
Apr 09 Python
在Python中操作字典之setdefault()方法的使用
May 21 Python
浅谈function(函数)中的动态参数
Apr 30 Python
Tensorflow之构建自己的图片数据集TFrecords的方法
Feb 07 Python
python使用turtle库与random库绘制雪花
Jun 22 Python
python os.listdir按文件存取时间顺序列出目录的实例
Oct 21 Python
详解pyenv下使用python matplotlib模块的问题解决
Nov 29 Python
python cumsum函数的具体使用
Jul 29 Python
python字典排序的方法
Oct 12 Python
python错误调试及单元文档测试过程解析
Dec 19 Python
快速了解Python开发环境Spyder
Jun 29 Python
Python中读取文件名中的数字的实例详解
Dec 25 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
构建简单的Webmail系统
2006/10/09 PHP
常见的PHP五种设计模式小结
2011/03/23 PHP
rephactor 优秀的PHP的重构工具
2011/06/09 PHP
PHP使用GIFEncoder类处理gif图片实例
2014/07/01 PHP
PHP编译安装时常见错误解决办法
2015/05/28 PHP
php表单习惯用的正则表达式
2017/10/11 PHP
ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
2019/03/11 PHP
php array_map()函数实例用法
2021/03/03 PHP
js弹窗代码 可以指定弹出间隔
2010/07/03 Javascript
JS多物体 任意值 链式 缓冲运动
2012/08/10 Javascript
zepto.js中tap事件阻止冒泡的实现方法
2015/02/12 Javascript
jQuery中dom元素上绑定的事件详解
2015/04/24 Javascript
基于Vue.js实现数字拼图游戏
2016/08/02 Javascript
JavaScript判断数组是否存在key的简单实例
2016/08/03 Javascript
微信小程序 在线支付功能的实现
2017/03/14 Javascript
Vue.js render方法使用详解
2017/04/05 Javascript
JS实现匀加速与匀减速运动的方法示例
2017/09/04 Javascript
JS实现简单的点赞与踩功能示例
2018/12/05 Javascript
微信小程序基于Taro的分享图片功能实践详解
2019/07/12 Javascript
layui框架与SSM前后台交互的方法
2019/09/12 Javascript
layui默认选中table的CheckBox复选框方法
2019/09/19 Javascript
Echarts实现多条折线可拖拽效果
2019/12/19 Javascript
ubuntu系统下 python链接mysql数据库的方法
2017/01/09 Python
对json字符串与python字符串的不同之处详解
2018/12/19 Python
python动态视频下载器的实现方法
2019/09/16 Python
Pandas时间序列基础详解(转换,索引,切片)
2020/02/26 Python
使用sublime text3搭建Python编辑环境的实现
2021/01/12 Python
css3编写浏览器背景渐变背景色的方法
2018/03/05 HTML / CSS
个人租房协议书
2014/04/09 职场文书
廉洁家庭事迹材料
2014/05/15 职场文书
环卫工人慰问信
2015/02/15 职场文书
五四青年节比赛演讲稿
2015/03/18 职场文书
加薪通知
2015/04/25 职场文书
MySQL连接控制插件介绍
2021/09/25 MySQL
MySQL分区表实现按月份归类
2021/11/01 MySQL
Golang 实现 WebSockets 之创建 WebSockets
2022/04/24 Golang