百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

OpenCV实战项目20讲(附源码)学完即可就业!

bigegpt 2024-08-06 11:49 2 浏览

最近有小伙伴推荐,希望可以将经典的项目整理一下,集成手册,便于小伙伴在日常的学习中使用。于是小编挑选了# OpenCV 的应用#专栏中的 20 篇经典内容,集结成册,便于小伙伴们阅读和学习。

本手册中主要涉及以下几部分,首先是对 OpenCV 中自带的基本函数进行介绍。其次是 OpenCV的实战项目,一方面是基于实际项目利用 OpenCV 实现特定对象的检测,例如车道线检测、路面的坑洼检测、等;另一方面是基于 OpenCV 实现图像增强,例如利用 OpenCV 消除运动所引起的图像模糊等。最后是 OpenCV 与深度学习等其他相结合实现图像分割、人脸检测、运动检测等难度较大的问题。

因为本手册是处于实时更新和维护的状态,因此会有一些内容变动,为了使小伙伴们获取准确的信息,因此手册中项目的源码不在书中给出。小伙伴们转发、转发、转发并评论回复【OpenCV实战项目 20 讲】就可以获得最新的源码信息。


手册中的具体内容如下:

  • 1. 使用 OpenCV 进行颜色分割
  • 2. 使用 OpenCV 实现图像覆盖
  • 3. 使用 OpenCV 进行图像全景拼接
  • 4. 使用 OpenCV 实现图像修复
  • 5. 自适应显着性的图像分割
  • 6. 使用 OpenCV 实现海岸线变化检测
  • 7. 使用 OpenCV 为视频中美女添加眼线
  • 8. 使用 OpenCV 实现猜词游戏
  • 9. 使用 OpenCV 进行检测坑洼
  • 10. 使用 OpenCV 实现车道线检测
  • 11. 使用 OpenCV 实现道路车辆计数
  • 12. 使用 C#和 OpenCV 实现人脸替换
  • 13. 使用 OpenCV 进行实时面部检测
  • 14. 使用 OpenCV 实现口罩检测
  • 15. 使用 OpenCV 预处理神经网络中的面部图像
  • 16. 基于 OpenCV 实现深蹲检测器
  • 17. 利用 OpenCV 实现基于深度学习的超分辨率处理
  • 18. 使用 OpenCV 实现社交距离检测器
  • 19. 使用 OpenCV 实现早期火灾检测系统
  • 20. 使用 OpenCV 构建运动检测器2020/7/29 使用OpenCV进行颜色分割

如果需要获取到这个【OpenCV实战项目20讲(附源码)更全面的文档的话帮忙转发、转发、转发一下然后再关注我私信回复“学习”得到获取方式吧!


使用OpenCV进行颜色分割

在滤波、变换、缩放等任务中,图像分割具有重要的意义。图像分割是将不同的对象划分为不同的部分,并将这些区域以明显的颜色或者记号标记出来。图像分割是使用轮廓、边界框等概念进行其他高级计算机视觉任务(例如对象分类和对象检测)的基础。良好的图像分割为我们后续的图像分类以及检测奠定了基础。

在计算机视觉中主要有3种不同的图像分割类型:

  • 1.颜色分割或阈值分割
  • 2.语义分割
  • 3.边缘检测

在本文里,我们将介绍基于颜色的图像分割,并通过OpenCV将其实现。小伙伴可能会问,当我们拥有像 Caffe和 Keras这样的工具时,为什么要使用拥有 21年历史的 OpenCV库。与Caffe和Keras等现代SOTA DL方法相比,OpenCV虽然在准确性方面有一些落后,但是运行速度相较于上述方法具有得天独厚的优势。

即使使用最著名的神经网络框架之一的YOLOv3进行对象检测时,其运行速度也是不尽如人意的。此外,Darknet使用OpenMP(应用程序编程接口)进行编译的时间几乎是OpenCV的18倍。这更加说明了使用OpenCV的速度是比较快速的。

颜色分割可用于检测身体肿瘤、从森林或海洋背景中提取野生动物的图像,或者从单一的背景图像中提取其他彩色物体。下面几幅图是图像分割的几个典型示例。

从以上示例中可以看出,尽管OpenCV是一种更快的方法,但是它对于图像的分割结果并不是非常的理想,有时会出现分割误差或者错误分割的情况

接下来我们将介绍如何通过OpenCV对图像进行颜色的分割。这里我们有一张含有鸟的图片,我们的目标是通过颜色分割尝试从图片中提取这只鸟。

首先我们导入完成该任务所需的所有库和这张图像:

  • import cv2 as cv
  • import matplotlib.pyplot as pltfrom PIL
  • import Image
  • !wget -nv https://static.independent.co.uk/s3fs-public/thumbnails/image/2018/04/10/19
  • img = Image.open('./bird.png')

接下来我们使用滤波器对该图像进行预处理,对图像进行模糊操作,以减少图像中的细微差异。在OpenCV中提供了4个内置的滤波器,以满足用户对图像进行不同滤波的需求。这4种滤波器的使用方式在下面的代码中给出。但是,针对于本文中需要分割的图像,我们并不需要将4种滤波器都使用。

  • blur = cv.blur(img,(5,5))
  • blur0=cv.medianBlur(blur,5)
  • blur1= cv.GaussianBlur(blur0,(5,5),0)
  • blur2= cv.bilateralFilter(blur1,9,75,75)

下图是图像滤波模糊后的结果:

接下来我们需要将图像从BGR(蓝绿色红色)转换为HSV(色相饱和度值)。为什么我们要从BGR空间中转到HSV空间中?因为像素B,G和R的取值与落在物体上的光相关,因此这些值也彼此相关,无法准确描述像素。相反,HSV空间中,三者相对独立,可以准确描述像素的亮度,饱和度和色度。

  • hsv = cv.cvtColor(blur2, cv.COLOR_BGR2HSV)

这个操作看似很小,但当我们尝试找到要提取的阈值或像素范围时,它会使我们的工作变得更加简单。

接下来是“颜色分割”的最重要一步,即“阈值分割”。这里我们将确定要提取的所有像素的阈值。使用OpenCV进行颜色分割中最重要步骤——阈值分割,这可能是一个相当繁琐的任务。即使我们可能想到通过使用颜色选择器工具来了解像素值,但是仍然需要进行不断的尝试,以便在所有像素中获取期望的像素,有些时候这也可能是一项艰巨的任务。具体操作如下:

  • low_blue = np.array([55, 0, 0])
  • high_blue = np.array([118, 255, 255])
  • mask = cv.inRange(hsv, low_blue, high_blue)

上面代码中最后一行的“Mask”将所有不在描述对象范围内的其他像素进行覆盖。程序运行结果如下图所示:

接下来,运行最后的代码以显示由Mask作为边界的图像。所使用的代码和程序运行结果在下面给出:

  • res = cv.bitwise_and(img,img, mask= mask)

那么通过上面的方式,我们就实现了基于颜色的图像分割,感兴趣的小伙伴们可以通过上面的代码和步骤进行尝试,看看能否满足自己的图像分割需求。


使用OpenCV实现图像覆盖

每张图像都包括RGB三个通道,分别代表红色、绿色和蓝色,使用它们来定义图像中任意一点的像素值,红绿蓝的值在0-255之间。

例如:一个像素值[255,0,0]代表全部为红色,像素值[255,255,0]是红色和绿色的混合,将显示为黄色。

但是,如果使用OpenCV读取图像,它将以BGR格式生成图像,那么[255,0,0]将代表蓝色。


使用OpenCV读取一张图像

任何图像都可以通过OpenCV使用cv2.imread()命令读取。不过,OpenCV不支持HEIC格式的图像,所以不得不使用其它类型的库,如Pillow来读取HEIC类型的图像(或者先将它们转换为JPEG格式)

  • import cv2image = cv2.imread(‘image.jpg’)

当读取图像之后,如果有必要的话可以将其从BGR格式转换为RGB格式,通过使用cv2.cvtColor()命令实现。

  • image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  • image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

覆盖

图像可以看作是是一堆像素值以类似矩阵的格式存储。任何像素的值都可以独立于其他像素进行更改。这里有一张图像,使用OpenCV读取图像:

  • image_1 = cv2.imread(‘image_1.jpg’)
  • print(image_1)

这里将给出矩阵形式的一系列像素值

  • array([[[107, 108, 106],[107, 108, 106],[107, 108, 106],…,[ 77, 78, 76],[ 77, 78, 76]

如果只改变图像某一区域的像素值,比如更改为[0,0,0],这部分区域将变成黑色,因为这是颜色为黑色的像素值。同样,如果将像素值更改为[255,0,0],则该区域将变为蓝色(OpenCV以BGR格式读取图像)。

  • image_1[50: 100, 50:100] = [255, 0, 0]

同样,这些像素值可以被另一幅图像替换,只需通过使用该图像的像素值。

为了做到这一点,我们需要将覆盖图像修改为要替换的像素值的大小。可以通过使用cv2.resize()函数来实现

使用OpenCV实现图像覆盖

  • image_2 = cv2.imread(‘image_2.jpg’)
  • resized_image_2 = cv2.resize(image_2, dsize=(100, 100))

其中,dsize 代表图像要被修改的尺寸。

现在,可以将第二张图像够覆盖在第一张图片的上面

  • image_1[50:150, 50:150] = resized_image_2


覆盖PNG图像

与JPEG图像不同,PNG图像有第四个通道,它定义了给定像素的ALPHA(不透明度)。

除非另有规定,否则OpenCV以与JPEG图像相同的方式读取PNG图像。

为了读取带有Alpha值的PNG图像,我们需要在读取一张图像时指定标志cv2.IMREAD_UNCHANGED。现在,这个图像已经有了四个通道:BGRA

  • image_3 = cv2.imread(‘image_3.png’, cv2.IMREAD_UNCHANGED)
  • print(image_3)
  • array([[[0 0 0 0][0 0 0 0][0 0 0 0]…[0 0 0 0][0 0 0 0][0 0 0 0]]…[[0 0 0 0][0 0 0 0]


使用OpenCV实现图像覆盖

然而,这个图像有4个通道,但是我们的JPEG图像只有3个通道,所以这些值不能简单地替换。

我们需要在我们的JPEG图像中添加一个虚拟通道。

为此,我们将使用 numpy。可以使用pip install numpy命令安装它。

numpy提供了一个函数numpy.dstack() 来根据深度叠加值。

首先,我们需要一个与图像大小相同的虚拟数组。

为了创建虚拟通道,我们可以使用numpy.ones()函数创建一个数组。

  • import numpy as npones = np.ones((image_1.shape[0], image_1.shape[1]))*255
  • image_1 = np.dstack([image_1, ones])

我们将其数组与255相乘,因为alpha通道的值也存在于0-255之间。

现在,我们可以用PNG图像替换图像的像素值。

  • image_1[150:250, 150:250] = image_3

然而,它不会给出期望的结果,因为我们将alpha通道的值改为了零


使用OpenCV实现图像覆盖

https://mp.weixin.qq.com/s?__biz=MzU0NjgzMDIxMQ==&mid=2247488514&idx=1&sn=6d3d315b30e9c736ecf23ab8816dac19&chksm=fb56f6ee… 5/6

我们只需要替换那些具有非零值的像素值。为了做到这一点,我们可以通过检查每个像素值和替换非零值来强行执行,但这很耗时。

这里有一个更好的方法。我们可以获取要覆盖图像的alpha值。

  • alpha_image_3 = image_3[:, :, 3] / 255.0

我们将像素值除以255.0,以保持值在0-1之间。现在,我们可以简单的取每个图像的alpha值和每个通道的图像像素值的元素乘积,并取它们的和。

image_1 和image_3的alpha之和需要等于255。因此,我们可以创建另一个数组,其中包含和等于255的所需alpha值。

  • alpha_image = 1 — alpha_image_3

现在,我们可以简单的取每个图像的alpha值和每个通道的图像像素值的元素乘积,并取它们的和。

  • for c in range(0, 3): image_1[150:250, 150:250, c] = ((alpha_image*image_1[150:250,

如果需要获取到这个【OpenCV实战项目20讲(附源码)更全面的文档的话帮忙转发、转发、转发一下然后再关注我私信回复“学习”得到获取方式吧!

内容太多,关注小编持续更新哟~

相关推荐

Linux 系统启动完整流程

一、启动系统流程简介如上图,简述系统启动的大概流程:1:硬件引导UEFi或BIOS初始化,运行POST开机自检2:grub2引导阶段系统固件会从MBR中读取启动加载器,然后将控制权交给启动加载器GRU...

超专业解析!10分钟带你搞懂Linux中直接I/O原理

我们先看一张图:这张图大体上描述了Linux系统上,应用程序对磁盘上的文件进行读写时,从上到下经历了哪些事情。这篇文章就以这张图为基础,介绍Linux在I/O上做了哪些事情。文件系统什么是...

linux入门系列12--磁盘管理之分区、格式化与挂载

前面系列文章讲解了VI编辑器、常用命令、防火墙及网络服务管理,本篇将讲解磁盘管理相关知识。本文将会介绍大量的Linux命令,其中有一部分在“linux入门系列5--新手必会的linux命令”一文中已经...

Linux环境下如何设置多个交叉编译工具链?

常见的Linux操作系统都可以通过包管理器安装交叉编译工具链,比如Ubuntu环境下使用如下命令安装gcc交叉编译器:sudoapt-getinstallgcc-arm-linux-gnueab...

可算是有文章,把Linux零拷贝技术讲透彻了

阅读本文大概需要6.0分钟。作者:卡巴拉的树链接:https://dwz.cn/BaQWWtmh本文探讨Linux中主要的几种零拷贝技术以及零拷贝技术适用的场景。为了迅速建立起零拷贝的概念...

linux软链接的创建、删除和更新

大家都知道,有的时候,我们为了省下空间,都会使用链接的方式来进行引用操作。同样的,在系统级别也有。在Windows系列中,我们称其为快捷方式,在Linux中我们称其为链接(基本上都差不多了,其中可能...

Linux 中最容易被黑客动手脚的关键目录

在Linux系统中,黑客攻击后常会针对关键目录和文件进行修改以实现持久化、提权或隐藏恶意活动。本文介绍下黑客最常修改的目录及其手法。一、/etc目录关键文件有:/etc/passwd和/et...

linux之间传文件命令之Rsync傻瓜式教程

1.前言linux之间传文件命令用什么命令?本文介绍一种最常用,也是功能强大的文件同步和传输工具Rsync,本文提供详细傻瓜式教程。在本教程中,我们将通过实际使用案例和最常见的rsync选项的详细说...

Linux下删除目录符号链接的方法

技术背景在Linux系统中,符号链接(symlink)是一种特殊的文件,它指向另一个文件或目录。有时候,我们可能需要删除符号链接,但保留其指向的目标目录。然而,在删除符号链接时可能会遇到一些问题,例如...

阿里云国际站注册教程:aa云服务器怎么远程链接?

在全球化的今天,互联网带给我们无以计数的便利,而云服务器则是其中的重要基础设施之一。这篇文章将围绕阿里云国际站注册、aa云服务器如何远程链接,以及服务器安全防护如Ddos防火墙、网站应用防护waf防火...

Linux 5.16 网络子系统大范围升级 多个新适配器驱动加入

Linux在数据中心中占主导地位,因此每个内核升级周期的网络子系统变化仍然相当活跃。Linux5.16也不例外,周一最新与网络相关的更新加入了大量的驱动和新规范的支持。一个较新硬件的驱动是Realt...

搭建局域网文件共享服务(Samba),手机电脑都能看喜欢的影视剧

作为一名影视爱好者,为了方便地观看自己喜欢的影视作品,在家里搞一个专门用来存放电影的服务器是有必要的。蚁哥选则用一台Ubuntu系统的电脑做为服务器,共享影音文件,其他同一个局域网内的电脑或手机可以...

分享一个实用脚本—centos7系统巡检

概述这周闲得慌,就根据需求写了差不多20个脚本(部分是之前分享过的做了一些改进),今天主要分享一个给平时运维人员用的centos7系统巡检的脚本,或者排查问题检查系统情况也可以用..实用脚本#!/bi...

Linux 中创建符号链接的方法

技术背景在Linux系统里,符号链接(SymbolicLink),也被叫做软链接(SoftLink),是一种特殊的文件,它指向另一个文件或者目录。符号链接为文件和目录的管理带来了极大的便利,比...

一文掌握 Linux 符号链接

符号链接(SymbolicLink),通常被称为“软链接”,是Linux文件系统中一种强大而灵活的工具。它允许用户创建指向文件或目录的“快捷方式”,不仅简化了文件管理,还在系统配置、软件开发和日...