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使用chardet判断字符串编码的方法
Mar 13 Python
修改Python的pyxmpp2中的主循环使其提高性能
Apr 24 Python
python 异常处理总结
Oct 18 Python
Python科学画图代码分享
Nov 29 Python
浅谈Series和DataFrame中的sort_index方法
Jun 07 Python
python登录WeChat 实现自动回复实例详解
May 28 Python
Python自定义函数计算给定日期是该年第几天的方法示例
May 30 Python
Python 虚拟空间的使用代码详解
Jun 10 Python
python单向循环链表原理与实现方法示例
Dec 03 Python
代码总结Python2 和 Python3 字符串的区别
Jan 28 Python
pytorch模型存储的2种实现方法
Feb 14 Python
python将logging模块封装成单独模块并实现动态切换Level方式
May 12 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无限分类的类
2007/01/02 PHP
PHP使用range协议实现输出文件断点续传代码实例
2014/07/04 PHP
WordPress中创建用户角色的相关PHP函数使用详解
2015/12/25 PHP
PHP自定义多进制的方法
2016/11/03 PHP
Mac系统下安装PHP Xdebug
2018/03/30 PHP
解决laravel查询构造器中的别名问题
2019/10/17 PHP
浅谈laravel 5.6 安装 windows上使用composer的安装过程
2019/10/18 PHP
PHPExcel实现的读取多工作表操作示例
2020/04/14 PHP
基于jQuery捕获超链接事件进行局部刷新代码
2012/05/10 Javascript
JS 跳转页面延迟2种方法
2013/03/29 Javascript
图片翻转效果具体实现代码
2014/01/09 Javascript
一个奇葩的最短的 IE 版本判断JS脚本
2014/05/28 Javascript
JS实现自动变换的菜单效果代码
2015/09/09 Javascript
jquery中ajax处理跨域的三大方式
2016/01/05 Javascript
jquery拖拽排序简单实现方法(效果增强版)
2016/02/16 Javascript
JavaScript中原型链存在的问题解析
2016/09/25 Javascript
React中jquery引用的实现方法
2017/09/12 jQuery
通过源码分析Vue的双向数据绑定详解
2017/09/24 Javascript
老生常谈JS中的继承及实现代码
2018/07/06 Javascript
解决vuecli3.0热更新失效的问题
2018/09/19 Javascript
详解实现一个通用的“划词高亮”在线笔记功能
2019/04/23 Javascript
webpack+express实现文件精确缓存的示例代码
2020/06/11 Javascript
通过滑动翻页效果实现和移动端click事件问题
2021/01/26 Javascript
[02:47]DOTA2亚洲邀请赛 HR战队出场宣传片
2015/02/07 DOTA
Python编程判断这天是这一年第几天的方法示例
2017/04/18 Python
浅谈Python中的可迭代对象、迭代器、For循环工作机制、生成器
2019/03/11 Python
Python3.5内置模块之os模块、sys模块、shutil模块用法实例分析
2019/04/27 Python
Python递归求出列表(包括列表中的子列表)的最大值实例
2020/02/27 Python
python中的插入排序的简单用法
2021/01/19 Python
CSS3 滤镜 webkit-filter详细介绍及使用方法
2012/12/27 HTML / CSS
办公室主任个人对照检查材料思想汇报
2014/10/11 职场文书
2014年工程工作总结
2014/11/25 职场文书
2015年街道办事处工作总结
2015/05/22 职场文书
HashMap实现保存两个key相同的数据
2021/06/30 Java/Android
利用 SQL Server 过滤索引提高查询语句的性能分析
2021/07/15 SQL Server
聊聊mysql都有哪几种分区方式
2022/04/13 MySQL