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中运行并行任务技巧
Feb 26 Python
Python使用Flask框架获取当前查询参数的方法
Mar 21 Python
Python中的匿名函数使用简介
Apr 27 Python
如何处理Python3.4 使用pymssql 乱码问题
Jan 08 Python
CentOS下使用yum安装python-pip失败的完美解决方法
Aug 16 Python
教你用Python创建微信聊天机器人
Mar 31 Python
根据DataFrame某一列的值来选择具体的某一行方法
Jul 03 Python
Pytorch Tensor的索引与切片例子
Aug 18 Python
Python3 实现爬取网站下所有URL方式
Jan 16 Python
Python基于gevent实现高并发代码实例
May 15 Python
Python参数传递及收集机制原理解析
Jun 05 Python
关于python中导入文件到list的问题
Oct 31 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
thinkphp实现数组分页示例
2014/04/13 PHP
PHP扩展开发入门教程
2015/02/26 PHP
js自动下载文件到本地的实现代码
2013/04/28 Javascript
变量声明时命名与变量作为对象属性时命名的区别解析
2013/12/06 Javascript
js判断是否为ie的方法小结
2014/01/13 Javascript
json实现前后台的相互传值详解
2015/01/05 Javascript
JS判断输入字符串长度实例代码(汉字算两个字符,字母数字算一个)
2016/08/02 Javascript
Three.js基础部分学习
2017/01/08 Javascript
BootStrap中jQuery插件Carousel实现轮播广告效果
2017/03/27 jQuery
jstree单选功能的实现方法
2017/06/07 Javascript
vue 挂载路由到头部导航的方法
2017/11/13 Javascript
详解vue-cli脚手架build目录中的dev-server.js配置文件
2017/11/24 Javascript
vue.js根据代码运行环境选择baseurl的方法
2018/02/28 Javascript
全站最详细的Vuex教程
2018/04/13 Javascript
vue element upload实现图片本地预览
2019/08/20 Javascript
vue.js 子组件无法获取父组件store值的解决方式
2019/11/08 Javascript
Python的“二维”字典 (two-dimension dictionary)定义与实现方法
2016/04/27 Python
一行Python代码过滤标点符号等特殊字符
2019/08/12 Python
Python3批量移动指定文件到指定文件夹方法示例
2019/09/02 Python
pandas 对group进行聚合的例子
2019/12/27 Python
flask框架蓝图和子域名配置详解
2020/01/25 Python
Tensorflow实现将标签变为one-hot形式
2020/05/22 Python
python3+opencv 使用灰度直方图来判断图片的亮暗操作
2020/06/02 Python
没编程基础可以学python吗
2020/06/17 Python
python退出循环的方法
2020/06/18 Python
Html5 语法与规则简要概述
2014/07/29 HTML / CSS
将一个文本文件的内容按倒序打印出来
2015/01/05 面试题
关爱女孩行动实施方案
2014/03/13 职场文书
cf搞笑广告词
2014/03/14 职场文书
法律系毕业生自荐信范文
2014/03/27 职场文书
食堂厨师岗位职责
2014/08/25 职场文书
大学生违纪检讨书300字
2014/10/25 职场文书
2014年企业党建工作总结
2014/12/18 职场文书
银行实习推荐信
2015/03/27 职场文书
教师节联欢会主持词
2015/07/04 职场文书
python 标准库原理与用法详解之os.path篇
2021/10/24 Python