openCV提取图像中的矩形区域

改编自详解利用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)
# 销毁所有创建出的窗口

运行效果

用到的图片

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • python-opencv在有噪音的情况下提取图像的轮廓实例

    对于一般的图像提取轮廓,介绍了一个很好的方法,但是对于有噪声的图像,并不能很好地捕获到目标物体. 比如对于我的鼠标,提取的轮廓效果并不好,因为噪声很多: 所以本文增加了去掉噪声的部分. 首先加载原始图像,并显示图像 img = cv2.imread("temp.jpg") #载入图像 h, w = img.shape[:2] #获取图像的高和宽 cv2.imshow("Origin", img) 然后进行低通滤波处理,进行降噪 blured = cv2.blur(i

  • 详解利用OpenCV提取图像中的矩形区域(PPT屏幕等)

    前言 最近参加了大创项目,题目涉及到计算机视觉,学姐发了个修正图像的博客链接,于是打算用这个题目入门OpenCV. 分析问题 照片中的PPT区域总是沿着x,y,z三个轴都有倾斜(如下图),要想把照片翻转到平行位置,需要进行透视变换,而透视变换需要同一像素点变换前后的坐标.由此可以想到,提取矩形区域四个角的坐标作为变换前的坐标,变换后的坐标可以设为照片的四个角落,经过投影变换,矩形区域将会翻转并充满图像. 因此我们要解决的问题变为:提取矩形的四个角落.进行透视变换. 提取矩形角落坐标 矩形的检测主

  • openCV提取图像中的矩形区域

    改编自详解利用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 shr

  • OpenCV提取图像中圆线上的数据具体流程

    目录 需求说明 具体流程 功能函数 C++测试代码 测试效果 总结 需求说明 在对图像进行处理时,经常会有这类需求:客户想要提取出图像中某条直线.圆线或者ROI区域内的感兴趣数据,进行重点关注.该需求在图像检测领域尤其常见.ROI区域一般搭配Rect即可完成提取,直线和圆线数据的提取没有现成的函数,需要自行实现. 直线的提取见: OpenCV获取图像中直线上的数据具体流程 而圆线的提取则是本文要将的内容,对圆线而言,将线上某点作为起点,沿顺时针或逆时针方向依次提取感兴趣数据,可放置在容器中.那么

  • 使用OpenCV检测图像中的矩形

    本文实例为大家分享了OpenCV检测图像中矩形的具体代码,供大家参考,具体内容如下 前言 1.OpenCV没有内置的矩形检测的函数,如果想检测矩形,要自己去实现. 2.我这里使用的OpenCV版本是3.30. 矩形检测 1.得到原始图像之后,代码处理的步骤是: (1)滤波增强边缘. (2)分离图像通道,并检测边缘. (3) 提取轮廓. (4)使用图像轮廓点进行多边形拟合. (5)计算轮廓面积并得到矩形4个顶点. (6)求轮廓边缘之间角度的最大余弦. (7)画出矩形. 2.代码 //检测矩形 //

  • OpenCV选择图像中矩形区域并保存

    本文实例为大家分享了OpenCV选择图像中矩形区域并保存的具体代码,供大家参考,具体内容如下 根据<Learning OpenCV>中的example4.1改写: // An example program in which the // user can draw boxes on the screen. // //#include <cv.h> //#include <highgui.h> #include "opencv2/imgproc/imgproc

  • OpenCV识别提取图像中的水平线与垂直线

    本文实例为大家分享了OpenCV识别提取图像中的水平线与垂直线,供大家参考,具体内容如下 1).原理 图像形态学操作时候,可以通过自定义的结构元素实现结构元素 对输入图像一些对象敏感.另外一些对象不敏感,这样就会让敏感的对象改变而不敏感的对象保留输出.通过使用两个最基本的形态学操作 – 膨胀与腐蚀,使用不同的结构元素实现对输入图像的操作.得到想要的结果. -膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值 -腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值 常见的形状:矩形.园.直线

  • C#使用OpenCV剪切图像中的圆形和矩形的示例代码

    前言 本文主要介绍如何使用OpenCV剪切图像中的圆形和矩形. 准备工作 首先创建一个Wpf项目--WpfOpenCV,这里版本使用Framework4.7.2. 然后使用Nuget搜索[Emgu.CV],如下图. 这里的Emgu.CV选择4.3.0.3890版本,然后安装Emgu.CV和Emgu.CV.runtime.windows. 使用OPenCV剪切矩形 现在,我们进入项目,进行OPenCV的调用. 首先引入命名空间,如下: using Emgu.CV; using Emgu.CV.Cv

  • 使用Python和OpenCV检测图像中的物体并将物体裁剪下来

    介绍 硕士阶段的毕设是关于昆虫图像分类的,代码写到一半,上周五导师又给我新的昆虫图片数据集了,新图片中很多图片很大,但是图片中的昆虫却很小,所以我就想着先处理一下图片,把图片中的昆虫裁剪下来,这样除去大部分无关背景,应该可以提高识别率. 原图片举例(将红色矩形框部分裁剪出来)): step1:加载图片,转成灰度图 image = cv2.imread("353.jpg") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) step2:用Sob

  • opencv3.0识别并提取图形中的矩形的方法

    利用opencv来识别图片中的矩形. 其中遇到的问题主要是识别轮廓时矩形内部的形状导致轮廓不闭合. 1. 对输入灰度图片进行高斯滤波  2. 做灰度直方图,提取阈值,做二值化处理  3. 提取图片轮廓  4. 识别图片中的矩形  5. 提取图片中的矩形 1.对输入灰度图片进行高斯滤波 cv::Mat src = cv::imread("F:\\t13.bmp",CV_BGR2GRAY); cv::Mat hsv; GaussianBlur(src,hsv,cv::Size(5,5),0

  • OpenCV实现图像连通域

    图像的连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域,连通域分析是指在图像中寻找出彼此互相独立的连通域并将其标记出来. 一般情况下,一个连通域内只包含一个像素值,因此为了防止像素值波动对提取不同连通域的影响,连通域分析常处理的是二值化后的图像. 4-邻域和8-邻域: 常用的图像邻域分析法有两遍扫描法和种子填充法.两遍扫描法会遍历两次图像,第一次遍历图像时会给每一个非0像素赋予一个数字标签,当某个像素的上方和左侧邻域内的像素已经有数字标签时,取两者中的最小值作为当前像素的标签,否则赋予

随机推荐