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正则表达式去掉数字中的逗号(python正则匹配逗号)
Dec 25 Python
python求pi的方法
Oct 08 Python
python numpy函数中的linspace创建等差数列详解
Oct 13 Python
Python 多进程并发操作中进程池Pool的实例
Nov 01 Python
Python实现图片滑动式验证识别方法
Nov 09 Python
教你使用python画一朵花送女朋友
Mar 29 Python
pytorch 把MNIST数据集转换成图片和txt的方法
May 20 Python
selenium在执行phantomjs的API并获取执行结果的方法
Dec 17 Python
Python饼状图的绘制实例
Jan 15 Python
详解pycharm连接不上mysql数据库的解决办法
Jan 10 Python
Window版下在Jupyter中编写TensorFlow的环境搭建
Apr 10 Python
Python request post上传文件常见要点
Nov 20 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
星际争霸任务指南——人族
2020/03/04 星际争霸
BBS(php &amp; mysql)完整版(四)
2006/10/09 PHP
用文本文件制作留言板提示(上)
2006/10/09 PHP
PHP与SQL注入攻击[三]
2007/04/17 PHP
PHP中执行cmd命令的方法
2014/10/11 PHP
判断是否输入完毕再激活提交按钮
2006/06/26 Javascript
精心挑选的15个jQuery下拉菜单制作教程
2012/06/15 Javascript
用jquery等比例控制图片宽高的具体实现
2014/01/28 Javascript
对js关键字命名的疑问介绍
2014/04/25 Javascript
js数组与字符串的相互转换方法
2014/07/09 Javascript
JavaScript获取网页支持表单字符集的方法
2015/04/02 Javascript
jQuery表单美化插件jqTransform使用详解
2015/04/12 Javascript
JS实现转动随机数抽奖特效代码
2020/04/16 Javascript
AngularJS表单和输入验证实例
2016/11/02 Javascript
js实现HashTable(哈希表)的实例分析
2016/11/21 Javascript
javascript稀疏数组(sparse array)和密集数组用法分析
2016/12/28 Javascript
JS如何设置元素样式的方法示例
2017/08/28 Javascript
Node.js 多线程完全指南总结
2019/03/27 Javascript
Vue 进阶之路(三)
2019/04/18 Javascript
微信小程序前端自定义分享的实现方法
2019/06/13 Javascript
使用Webpack提升Vue.js应用程序的4种方法(翻译)
2019/10/09 Javascript
vue3.0 加载json的方法(非ajax)
2020/10/26 Javascript
[01:03:36]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第二场 1月26日
2021/03/11 DOTA
python根据经纬度计算距离示例
2014/02/16 Python
Python THREADING模块中的JOIN()方法深入理解
2015/02/18 Python
python中pandas.DataFrame对行与列求和及添加新行与列示例
2017/03/12 Python
Python实现带参数与不带参数的多重继承示例
2018/01/30 Python
python3.6.5基于kerberos认证的hive和hdfs连接调用方式
2020/06/06 Python
Python实现冒泡排序算法的完整实例
2020/11/04 Python
Python创建文件夹与文件的快捷方法
2020/12/08 Python
pycharm 配置svn的图文教程(手把手教你)
2021/01/15 Python
HTML5的download属性详细介绍和使用实例
2014/04/23 HTML / CSS
在C中是否有模拟继承等面向对象程序设计特性的好方法
2012/05/22 面试题
经贸日语专业自荐信
2014/09/02 职场文书
综合管理员岗位职责
2015/02/11 职场文书
Apache Hudi集成Spark SQL操作hide表
2022/03/31 Servers