本系列专栏写作方式

本系列专栏将采用首创的问答式写作形式,快速让你学习到 OpenCV 的初级、中级、高级知识。

7. 在 Python OpenCV 寻找目标区域以及边缘扩展的解决方案

针对图像的特定区域进行操作,在 OpenCV 中被称作 ROI ,即目标区域或者叫做感兴趣区域,在处理图像的时候,可以先定位一个目标区域,然后再在该区域进行细节筛选,这样可以提高我们程序的速度和准确性。

实现 ROI 操作其实就是采用 numpy 对图像进行操作

例如下述测试代码,我们需要寻找图像指定区域

import cv2
import numpy as npsrc = cv2.imread("./7_img.jpg")
# cv2.imshow("src",src)
cv2.imshow("src",src)
# 注意后面的列表获取,格式为 [rows,cols]
roi_img = src[50:150, 100:150]
print(roi_img.shape)
cv2.imshow("roi_img", roi_img)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果如下所示,尤其需要注意的是代码注释部分的说明,在做 ROI 的时候,需要筛选的区域用伪代码表示如下 src[起始行像素:结束行像素,起始列像素:结束列像素]

这个地方经常出现的一个 BUG 如下

error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'

很多博客中会写是图片文件中文路径的问题,但是其实这只是一种结果,真正的原因是图像出现了空结构,也就是读取图像的 shape 属性如果展示内容为 (0,0,3),那必然出现上述错误。例如下面代码就存在该问题。

import cv2
import numpy as npsrc = cv2.imread("./7_img.jpg")
# cv2.imshow("src",src)roi_img = src[50:50, 100:100]
print(roi_img.shape)
cv2.imshow("roi_img", roi_img)
cv2.waitKey()
cv2.destroyAllWindows()

确定目标区域,最大的难点就是坐标问题,你可以多次尝试一下,直到记住目标区域的定位方式。

获取到 ROI 区域之后,可以对其进行修改,例如,下述代码将 ROI 区域设置为灰度图像

import cv2
import numpy as npsrc = cv2.imread("./7_img.jpg")
# cv2.imshow("src",src)
cv2.imshow("src", src)
# 注意后面的列表获取,格式为 [rows,cols]
roi_img = src[50:150, 100:150]
gray = cv2.cvtColor(roi_img, cv2.COLOR_BGR2GRAY)src[50:150, 100:150] = gray
cv2.imshow("src", src)
cv2.waitKey()
cv2.destroyAllWindows()

直接运行该代码,会出现如下错误

ValueError: could not broadcast input array from shape (100,50) into shape (100,50,3)

因为合并的图像通道数不对,接下来你需要做的是将灰度图扩展为三通道形式,使用下述代码即可实现。

# 灰度图扩展到 3 通道
grays = np.stack((gray,)*3, axis=-1)
print(grays)
src[50:150, 100:150] = grays

其中用到了 numpy.stack(arrays, axis=0) 函数,将数组进行连接。修改代码之后得到的运行结果如下所示。

OopenCV 图像的拆分与合并

上述案例你已经掌握了图像目标区域获取的方式,接下来我们对图像进行一下通道的拆分与合并,具体会使用到两个函数,分别是 cv2.mergecv2.split

两个函数的原型可以直接获取

# splite 函数原型
mv = cv2.split(m[, mv])
# merge 函数原型
dst = cv2.merge(mv[, dst])

下面进行图像的拆分,并通过 matplotlib 库进行图片的展示:

import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread("7_img.jpg")b, g, r = cv2.split(src)
plt.subplot(131)
plt.imshow(b, "gray")
plt.title("b")plt.subplot(132)
plt.imshow(g, "gray")
plt.title("g")plt.subplot(133)
plt.imshow(r, "gray")
plt.title("r")plt.show()

运行之后可以获取每个通道的灰度图,cv2.split 执行的效率并不高,所以你使用的图像如果过大,记得稍等片刻。

针对每个通道还可以进行拆分赋值,例如,你可以将 BGR 顺序颠倒,形成不同色彩的图片。

## 交换通道顺序,进行合并
dst = cv2.merge((r,g,b))
cv2.imshow("dst",dst)cv2.waitKey()

运行之后,可以得到对应的效果。

cv2.mergecv2.split 函数参数列表,请重点比对原型进行学习。

如果你想要单独修改某一通道值,可以使用 numpy 进行操作,例如我们将 R 通道的像素值修改为 0,使用下述代码即可

import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread("7_img.jpg")
src[:,:,2] = 0cv2.imshow("src1",src)
src[:,:,2] = 255cv2.imshow("src2",src)
cv2.waitKey()

OpenCV 图像边缘扩展

接下来将要学习的函数是图像扩边操作,使用 cv2.copyMakeBorder 函数,函数原型如下:

dst = cv2.copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]])

先掌握几个核心参数 src 原图像,top,bottom,left,right分别表示在原图四周扩充边缘的大小。

关于 borderType 参数,表示的需要填充的边界类型,该值有多种取值,建议是自行尝试,我们采用其中一个优先进行说明。

import cv2
from matplotlib import pyplot as pltsrc = cv2.imread("color.jpg")
# 后续绘图使用 pyplot ,所以切换一下颜色通道的排序,相当于从 BGR 转换为 RGB
b, g, r = cv2.split(src)
img = cv2.merge([r, g, b])replicate = cv2.copyMakeBorder(img, 20, 20, 20, 20, cv2.BORDER_REPLICATE)print("原图形状",src.shape)
print("扩充边界之后的形状",replicate.shape)

打印结果,注意像素的宽度和高度都扩展了 40,扩展之后的图片,你可以自行比对。

原图形状 (624, 500, 3)
扩充边界之后的形状 (664, 540, 3)

图像扩展边界最后一个参数 borderType 有如下取值

  • cv2.BORDER_CONSTANT:固定值填充;
  • cv2.BORDER_REFLECT_101 或者 cv2.BORDER_DEFAULT :取镜像对称的像素填充;
  • cv2.BORDER_REPLICATE:重复最后一个像素;
  • cv2.BORDER_WRAP:取镜像。

结合上文,可以实现这样一个效果,找到 ROI 区域,然后对其进行边缘扩展。

import cv2
from matplotlib import pyplot as pltsrc = cv2.imread("7_img.jpg")
# 后续绘图使用 pyplot ,所以切换一下颜色通道的排序,相当于从 BGR 转换为 RGB
b, g, r = cv2.split(src)
img = cv2.merge([r, g, b])roi_img = img[120:170,200:250]dst = cv2.copyMakeBorder(roi_img, 2, 2, 2, 2, cv2.BORDER_CONSTANT,value=[0,0,255])img[118:172,198:252] = dst
plt.imshow(img)
plt.title('img')
plt.show()

执行代码之后,我们在原图找到某个区域,然后对其进行边缘扩展,实现了一个矩形的框选操作,效果如下:

番外7. 在 Python OpenCV 寻找目标区域以及边缘扩展的解决方案相关推荐

  1. python opencv实现目标区域裁剪

    这个任务是自己在项目中数据处理的一部分内容,待处理的图片如下所示: 我需要将目标区域给裁剪出来,要不然在后期训练网络的时候整幅图像过大,且目标区域过小,得到结果不好,还会加剧计算量.在网上找了各个大佬 ...

  2. #3使用html+css+js制作网页 番外篇 使用python flask 框架 (I)

    #3使用html+css+js制作网页 番外篇 使用python flask 框架(I 第一部) 0. 本系列教程 1. 准备 a.python b. flask c. flask 环境安装 d. f ...

  3. Python+Opencv身份证号码区域提取及识别实现

    前端时间智能信息处理实训,我选择的课题为身份证号码识别,对中华人民共和国公民身份证进行识别,提取并识别其中的身份证号码,将身份证号码识别为字符串的形式输出.现在实训结束了将代码发布出来供大家参考,识别 ...

  4. python opencv kcf_pybind11—目标跟踪demo(KCF,python version)

    前言 pybind11功能强大,将C++ 程序包装为python接口,对于不太熟悉C++的同学只需要调用python接口即可,方便实用.之前的一系列pybind11文章大多数是基础的用法,本人学习py ...

  5. Python+opencv学习记录8:边缘保留滤波(EPF)

    文章目录 1.高斯双边模糊 1.1原理 1.2代码解析 2.均值迁移模糊 2.1.原理 2.2.代码解析 完整代码 1.高斯双边模糊 1.1原理 前文提到的高斯模糊只考虑了像素空间的分布,而没有考虑差 ...

  6. Python+Opencv寻找图像中最亮的区域

    目录 一.场景需求解读 二.算法原理简介 三.算法代码实现 四.代码运行步骤 五.算法效果展示和分析 六.思维扩展 参考资料 注意事项 一.场景需求解读   在有些现实场景中,我们需要去使用算法自动的 ...

  7. 人工智能基础(高中版)教材补充和资源分享之番外篇 Cozmo+Python+ROS+AI

    ROS Melodic的迷失与救赎::https://blog.csdn.net/column/details/28058.html GitChat::沉迷机器人操作系统的一个理由和四种修仙秘籍 原文 ...

  8. 学习笔记(番外篇)——python批量转换图片格式

    2019独角兽企业重金招聘Python工程师标准>>> #-*- coding:utf-8 -*- from PIL import Image import os import gl ...

  9. python—opencv 实时视频目标追踪

    功能: 1.获取摄像头,实时显示 2.鼠标获取第一帧中的目标roi区域 3.在视频中实时对目标进行追踪. 4.两种目标追踪的方式:'meanshift','camshift' 5.保存视频 impor ...

  10. Python番外篇:Python代码生成春联 三种版本

    Hello,大家好,我是wangzirui32,今天就是虎年春节了,先祝大家虎虎生威,虎年大吉!愿大家在新的一年里万事如意,心想事成! 文章目录 1. 普通版本 1.1 引入所需模块 1.2 生成春联 ...

最新文章

  1. ASCII码对应表,ASCII码值的大小顺序
  2. # 2021华为软件精英挑战赛C/C++——build.sh/build_and_run.sh/CodeCraft_zip.sh注释
  3. seajs学习心得和新产品福利
  4. python 判断是不是汉字危机阅读答案_《汉字危机》阅读练习及答案
  5. 前缀 中缀 后缀表达式
  6. 具有ESB,API管理和Now ..服务网格的应用程序网络功能。
  7. linux里的run-level,linux run level 为何物
  8. 爱奇艺CEO龚宇呼吁网络电影涨价:6块钱太低了
  9. 愚人节谁最皮?华为宣布攻克兽语,小米6复刻版官宣,微信发万元红包...
  10. 一个程序段两个小问题
  11. linux 每日学一点《linux中让NMAP命令跟防火墙躲猫猫》
  12. 基于51单片机的交通灯设计
  13. 2-11 CAD基础 镜像(mirror)
  14. 【OpenCV图像处理】十五、图像空域滤波(上)
  15. 【机器学习基础】EM算法详解及其收敛性证明
  16. 使用ps完成手写数字图片(用于验证手写数字模型或制作数据集)
  17. 比比看手机安全软件谁更强?【系统收藏】
  18. 不使用Ultra Liberarion软件导出BXL文件的方法
  19. webpack版本升级的差异大版本更迭
  20. RabbitMQ异常:ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN.

热门文章

  1. Java中分布式概念
  2. 前端工具使用记录(css/js/htm)
  3. java poi 水印_poi excel如何设置水印透明度
  4. 种草推荐redis客户端
  5. 转载——傅里叶变换概念及公式推导
  6. 华数机器人旋转编程_华数工业机器人编程 MOVE运动指令
  7. JAVA 三个框架结合运用思路_SSM框架的整合与使用——实现简单的转账系统
  8. PDM系统服务器管理,PDM产品数据管理系统
  9. 浅谈文字编码和Unicode(中)[转]
  10. 2019就业率最高专业TOP20出炉,哪些专业最好找工作?