学习图像处理

2019-06-19 22:14:02 qq_15029743 阅读数 6968

       伴随着图像处理技术的发展,我们每天无时无刻都在接触着图像处理的一切,打开相机,设置美颜程度,伴随着快门键的按下,一张瘦脸磨皮的人像处理完成了。按下手机的解锁键,前置摄像头已经获取了你的人脸图像,并在你的脸上打上了若干个点,与数据库的信息进行比对,一次人像比对完成了。车辆行驶到单位校园门口,你的车牌已经被切割成一个个字母、数字与汉字,随着栏杆的抬起,又一次图像处理完成了。伴随着图像处理的广泛应用以及目前人工智能在图像领域的应用,更多的图像处理技术爆发式的增长,也更多的人投入到了这个领域的研究。作为一名行业从业者,如何学好图像处理就显得甚为棘手。博主作为一名“半路出家”的图像处理入门者,在这里也给各位读者分享一下一直以来的一些思考,因为本人水平有限,不妥之处还望见谅。

1、高山平顶上,尽是采樵翁。人人各怀刀斧意,未见山花映水红。        ——何权峰《眼界,决定你的世界》

        其实很多时候,我们都局限在自己的小平台里,沾沾自喜,而忽略了你身边技术的飞速发展,也许这种沉浸对于一些传统行业来说,淘汰一个人的速度是十几年甚至几十年,但是对于计算机领域来说,这一淘汰也许就是一瞬间,这也是为什么企业在招聘应届生事,一方面关注你的技能,但也非常关注你的学习能力(简单说就是你可以什么都不会,但你学的快不?但你愿意学不?),而这种学习能力往往是需要长时间培养锻炼的,举个例子:清华北大的学生永远不愁找不到工作,而去清华北大招聘的企业也往往最不看重你的专业,因为他们知道,这里有着国内学习能力最强的人。说的有点远了,回到刚刚的话题,其实给博主触动最深的还是看到了CSDN某大神的一篇博客《阿里巴巴(菜鸟) - 算法工程师(机器学习)提前批笔试面试总结》中面试环节面试官问的一个问题:介绍CVPR2018你最感兴趣一篇论文的工作?看到这里博主犹如当头一棒。自己也只是听说过CVPR,当然也会留意一些媒体的报道或者是推送,但是从来都没有认真的甚至说大致的浏览过每一年会议的文章内容甚至是会议目录。而自己也“井底之蛙”般的只能感叹自己也许将是接下来就被淘汰的那个。其实广一点说,我们的本科生或者研究生期间,可能你的实验室做的东西很low,亦或是你是一个“半路出家者”,或者我们的“出身”不是很好,这些都或多或少的会限制我们的眼界。但是我们自己不应该允许自己做那只“井底之蛙”,我们更应该关注或者说拥抱我们所处这个行业最新、最前沿的技术(比如2018CVPR的最佳论文《Taskonomy: Disentangling Task Transfer Learning》);关注我们这个领域的大牛(比如做计算机视觉我们一定绕不开李飞飞教授、做相机标定一定离不开张正友教授)。眼界决定我们的视野,这也是为什么很多顶尖的公司在招聘的时候一定会加上如下两条:1、所在实验室为国家重点实验室或者在国内顶尖的科研机构有过实习经历  2、在顶级会议发表过相关文章。会当凌绝顶,方能一览众山小!

这里,博主附上计算机视觉领域的CCF推荐会议:计算机视觉及图像处理领域会议,CCF推荐(A类,B类,C类),感兴趣的读者可以选取和你研究课题相关的较高水平的会议关注查看。

2、知其然与知其所以然。 ——《朱子语类》卷九《论知行》

        这里我们要说,很多人在从事图像处理工作的时候更多的是被动的被推着走,只知其然而不知其所以然,还是举个例子,我们都知道,图像处理的前期操作就是获取图像,而获取图像的一个重要途径就是通过相机获取图片,相机获取到的图片更多程度需要去标定矫正。好了,问题来了,很多人知道,我获取图像了,按照“前人所述”我需要进行相机标定,设置标定板、计算内外参数...一些列工作完成了,我们也得到了“前人所述”的内外参数,那接下来呢?我们怎么矫正呢?为什么要做矫正呢?不矫正对我的图像处理过程有什么影响呢?想必这个问题是很多读者没有考虑过的,博主也看了很多的博客,相机标定写内外参矩阵的大有人在,图像生动、推导详尽。但说获取这些参数只会该干什么的博客却是凤毛麟角。反观之,我们其实很多时候也都停留在这样的阶段,就是只知道,这个事情该这样,但是为什么要这样却知之甚少。

3、一门科学,只有当它成功地运用数学时,才能达到真正完善的地步。  ——马克思

        其实博主本人也是一个讨厌数学且数学不好的人,但是越是从事图像处理工作越深,越发觉得数学的重要性。数学也许就像是你的导师,你很多时候很讨厌,但是却绕不开。图像处理时我们会发现,图像在计算机内其实就是一个个矩阵,图像的处理很多时候就是数学变换,比如去噪(数学上的均值或者中值处理),比如放大缩小图像(数学上的插值和采样)等等,这里我们还是举一个例子:从事图像处理的人应该大部分都知道(最起码听说过)SIFT特征点检测算法,这里不展开论述,我们只拿其中的一个关键部分来说,SIFT算法中有两种方法,分别是:

a、使用LOG图像(高斯拉普拉斯变换图像):其步骤是:先将照片降采样,得到了不同分辨率下的图像金字塔。再对每层图像进行高斯卷积。这样一来,原本的图像金字塔每层只有一张图像,而卷积后,每层又增加了多张不同模糊程度下的照片。大概就是下图这样:

b、使用(DOG图像):DOG即高斯差分。构造高斯差分图像的步骤是:在获得LOG图像后,用其相邻的图像进行相减,得到所有图像重新构造的金字塔就是DOG金字塔。大概就是下图这样子:

        好了,问题来了,这一数学上的改进,能有多大的差距呢?我们可以看到,就是这样一个“看似简单”的改进可以使我们的运算量小一个数量级!数学有多重要!

        也许上面的过程有一些读者没看明白,什么又是高斯卷积又是图像相减的,太麻烦,那我们再介绍一种非常“简单”的特征点检测算法(FAST) ,有多“简单”呢?这里先放一张图:

        为了让大家简单易懂,这里我们简单的说原理,可能与实际不相符,简单说,就是你要找特征点P,那我在p周边画个圈,设置一个阈值,如果有若干个点大于这一阈值,我们就理解为p是特征点(阈值为9就是FAST9,阈值为11就是FAST11)。惊不惊喜,意不意外,就是这么好理解,而且这一算法的速度快,效果也不差。其实这种方法博主更多的理解为是一种数学上的改进。而我们纵观众多划时代的文章、方法、算法,其实其本质大多为数学方法在各个领域上应用的改进。学好数理化,走遍天下都不怕,数学,可怕却重要! 

4、如果我能看得更远一点的话,是因为我站在巨人的肩膀上。  ——牛顿

        伴随着计算机网络的发展,开源的趋势化(强调专利的微软收购了Github并主动开源了众多代码),我们可以找到更多的资源与资料(BaiDu,Google一键直达),一个个的开放图形库和开放图形软件(最常见的OpenGL、OpenCV),我们有着比以往任何时候更多的资源,也有着比以往人更多的机会接触到科技的最前沿(顶级会议大部分都是开源的,我们可以随意下载),这里博主特别强调,大胆的去使用这些工具,抱着书本往死里啃,问周边同学或老师有效,但这样的时代终将过去,信息交互的年代,每一个人都是一个信息源(有点像众包的概念),站在巨人肩膀上引领科技进步的人也许不是你我,但是你我可以更容易找到这个世界上的巨人在哪里了,我们的获取信息的渠道更多了,我们身边的信息源更多了(比如MOOC,我们可以倾听最好的老师讲课),这里说点题外话,推荐一部纪录片《互联网时代》,当时博主看的热血沸腾!回到主题,不主动拥抱这个时代的人一定会被时代所抛弃。能活到最后的人一定不是闭门造车的,一定是那个敢于攀登,寻找巨人的人。

5、工欲善其事,必先利其器。  ——《论语·卫灵公》

这里其实博主还是老生常谈的强调你的编程能力,我们都知道,一切的图像处理的最终实现都是程序,更是算法(硬件处理也有硬件程序、算法),而编程能力就好比士兵的枪、老师的粉笔。再好的想法如果不能付诸于一行行“冰冷”的算法最后都只能是镜中花、水中月。而选择哪门语言作为你的“枪”这里博主就不再赘述,直接放上之前写的一篇博客的内容:

Python?JAVA?C/C++?
      其实实验室也会有一些师弟师妹问我这个问题,我该选一门什么语言呢?当然,我在这里不去评论哪门语言的优劣好坏,仅仅针对每一门语言在找工作时选择的机会跟大家做一些分享,首先,如果你需要找工作时自己能多一些机会和选择,那么仅仅会MATLAB或者Python可能还是远远不够的,毕竟找工作时需求量最大的依旧是JAVA\C\C++相关的工程师,如果你仅仅会MATLAB或者Pyrthon,那么你找工作时可能只能选择算法相关类的工作,而这类工作,我们都知道,和你竞争的往往都是一些大佬,算法岗也因为其相对的高工资和低劳动强度而成为近两年来淘汰人数最多的岗位之一。

      所以,这里强烈建议如果有可能,请抽出时间选择JAVA\C\C++其中一门语言进行系统化的学习(这里我们只谈最常见的,PHP,GO等语言博主没有学过,也没有具体了解,就不在这里献丑了),当然选择JAVA你还可以转向安卓开发,C\C++则更加偏底层一些。这一切的选择基础需要你综合衡量,博主特别讨厌一些鼓吹某某语言万能无敌之类的话,举个例子C++的确可以坐界面,但显然,做界面C++不是最好的选择,合适的才是最好的,不是么?

6、你看江面平如镜,要看水底万丈深。  ——谚语

        我们很多人,其实也包括博主本人都有这个问题,就是用一个东西的时候想的不够深入,直至其表,不知其里,还是举个例子,我们每个人都应该知道的边缘检测算法,博主相信,用起来不难,网上搜一下代码,一搜一大片,有一定程序基础的人都可以轻松实现,但是深入思考,我们知道他的原理么?这里,博主将所有人分为几个等级,大家可以以边缘检测算法作为作为自己的对照,看看自己停留在哪个级别:

a、还没入门的“行外汉”:什么是边缘检测算法?不会怎么办?问周边人吧!

b、已经入门的“小菜鸟”:emm,好像有印象,去网上搜一下现成的程序,改一下图片输入就行了!

c、有思考的“程序猿”:算法每一个参数什么意思啊?我改一下会怎样?

d、负责任的“熟练工”:这个算法的原理究竟是什么样的?怎么就找到边缘了?找个博客看看!

e、企业抢着要的“大牛”:算法原理我看懂了,自己手撕代码试一下!

f、“大佬、科研工作者”:数学公式可能需要自己推一下,看能不能改进!

看看,一个简单的边缘检测算法我们就可以看到不同人的不同水平,你的思维深度更多时候可以决定你的高度!

7、思考可以构成一座桥,让我们通向新知识。 ——普朗克

      小时候爸爸妈妈就教会我们多问一问为什么,那时候最喜欢看的书也是《十万个为什么》,但是越长大越发现自己丧失了这种质疑和思考能力,我们更多时候的想法是“哪有那么多为什么!”。做项目,搞科研其实更多时候需要我们这种问问题的能力,就好比之前的例子:相机标定,为什么要标定?其实道理大家都懂,做到的却太少了,包括博主本人,这里写出这条大家共勉!

8、亡羊补牢,犹未迟也。  ——《战国策·楚策四》

        可能很多人看到博主写了这么多会觉得可能自己再某个或者某些领域的欠缺有点大,有些失落甚至灰心丧气。其实博主需要在文章的最后和大家打打气,我们发现了问题和漏洞只要积极去改变,就会发现事情就会朝着好的方向发展。谁能想到《三体》作者刘慈欣若干年前还在水电站工作?又有谁能想到阿里云的头头是一个哲学博士呢?最后一句话赠与自己也赠与能看到这篇文章的读者们共勉:改变,从当下开始!

2019-07-23 09:49:56 weixin_44692360 阅读数 698

图像处理基础学习(一)

【task1】初识opencv

一、什么是OpenCV的,它有哪些优势?
二、opencv安装和环境配置
三、了解数字图像的基本概念:像素,彩色图像,灰度图像,二值图像,图像算数操作
四、练习numpy的中阵列的基本操作
五、练习图像的加载,保存,以及算术操作

一、什么是OpenCV的,它有哪些优势?

(一)、Opencv(Open Source Computer Vision Library)
Opencv中文名:开源计算机视觉库,OpenCV于1999年由Intel建立,如今由Willow Garage提供支持。OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。最新版本是3.4 ,2017年12月23日发布。
(二)、Opencv的优势
(百度百科)
计算机视觉市场巨大而且持续增长,且这方面没有标准API,如今的计算机视觉软件大概有以下三种:
1、研究代码(慢,不稳定,独立并与其他库不兼容)
2、耗费很高的商业化工具(比如Halcon, MATLAB+Simulink)
3、依赖硬件的一些特别的解决方案(比如视频监控,制造控制系统,医疗设备)这是如今的现状,Opencv的优势是将标准的API将简化计算机视觉程序和解决方案的开发,OpenCV致力于成为这样的标准API。
OpenCV致力于真实世界的实时应用,通过优化的C代码的编写对其执行速度带来了可观的提升,并且可以通过购买Intel的IPP高性能多媒体函数库(Integrated Performance Primitives)得到更快的处理速度。下图为OpenCV与当前其他主流视觉函数库的性能比较。

在这里插入图片描述
这里分享几个获取资源的网站:

http://opencv.org

http://wiki.opencv.org.cn/

二、opencv安装和环境配置

这里说一下我使用的是anaconda+pycharm+opencv3.4.2.16版本
具体步骤就是下载anaconda和pycharm,之后再把anaconda搭载到pycharm,这里就不放截图了网上有很多教程可以看下
之后就是下载opencv
学习的时候建议下载Opencv3.4.2.16版本,最新版本因为版权问题有很多算法是无法实现的
下面放一下下载代码(后续有可能用到pytesseract所以提前下载)
pytesseract是google做的COR库,可以识别图片中的文字,一般用在爬虫登录时验证码的识别.

pip install opencv-python=3.4.2.16
pip install opencv-contrib-python=3.4.2.16
pip install pytesseract

完成之后调试下
这里截图一下运行代码
在这里插入图片描述
在这里插入图片描述

三、了解数字图像的基本概念:像素,彩色图像,灰度图像,二值图像,图像算数操作

下面总结下数字图像的基本概念(主要来源:《数字图像处理》第三版第二章 以及 百度百科)
(一)、像素:
1、由一个数字序列表示的图像中的一个最小单位。可以理解为一个二维数组的一个元素,其值大小表示灰度(强度)
2、像素是指由图像由的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。
3、可以将像素视为整个图像中不可分割的单位或者是元素。不可分割的意思是它不能够再切割成更小单位抑或是元素,它是以一个单一颜色的小格存在 。每一个点阵图像包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小。
(二)、彩色图像:
1、彩色图像,每个像素通常是由红(R)、绿(G)、蓝(B)三个分量来表示的,分量介于(0,255)。
在这里插入图片描述
(三)、灰度图像:
1、灰度:灰度是表明图像明暗的数值,即黑白图像中点的颜色深度,范围一般从0到255,白色为255 ,黑色为0,故黑白图片也称灰度图像。灰度值指的是单个像素点的亮度。灰度值越大表示越亮。
2、灰度级:灰度级表明图像中不同灰度的最大数量。灰度级越大,图像的亮度范围越大。
3、灰度分辨率:灰度级中可分辨的最小变化。通常说一副被量化为256级的图像有8比特的灰度分辨率。
4、灰度数字图像是每个像素只有一个采样颜色的图像。这类图像通常显示为从最暗黑色到最亮的白色的灰度,尽管理论上这个采样可以任何颜色的不同深浅,甚至可以是不同亮度上的不同颜色。灰度图像与黑白图像不同,在计算机图像领域中黑白图像只有黑白两种颜色,灰度图像在黑色与白色之间还有许多级的颜色深度。
5、灰度图像是二值图像的进化版本,是彩色图像的退化版,也就是灰度图保存的信息没有彩色图像多,但比二值图像多,灰度图只包含一个通道的信息,而彩色图通常包含三个通道的信息,单一通道的理解可以理解为单一波长的电磁波,所以,红外遥感,X断层成像等单一通道电磁波产生的图像都为灰度图,而且在实际中灰度图易于采集和传输等性质的存在导致基于灰度图像开发的算法非常丰富。
6、灰度图像(gray image)是每个像素只有一个采样颜色的图像,这类图像通常显示为从最暗黑色到最亮的白色的灰度,尽管理论上这个采样可以任何颜色的不同深浅,甚至可以是不同亮度上的不同颜色。灰度图像与黑白图像不同,在计算机图像领域中黑白图像只有黑色与白色两种颜色;但是,灰度图像在黑色与白色之间还有许多级的颜色深度。灰度图像经常是在单个电磁波频谱如可见光内测量每个像素的亮度得到的,用于显示的灰度图像通常用每个采样像素8位的非线性尺度来保存,这样可以有256级灰度(如果用16位,则有65536级)。

通常可以用opencv来实现彩色图像转变为灰度图像
这里放下代码

import cv2 as cv
import numpy as np


src = cv.imread("C:/Users/lenovo/PycharmProjects/learn/venv/3.jpg")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
get_image_info(src)
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
cv.imwrite("C:/Users/lenovo/PycharmProjects/learn/venv/result.png",gray)
cv.waitKey(0)
cv.destroyAllWindows()

实现图
在这里插入图片描述

(四)、二值图像
1、二值图像(Binary Image),按名字来理解只有两个值,0和1,0代表黑,1代表白,或者说0表示背景,而1表示前景。其保存也相对简单,每个像素只需要1Bit就可以完整存储信息。如果把每个像素看成随机变量,一共有N个像素,那么二值图有2的N次方种变化,而8位灰度图有255的N次方种变化,8为三通道RGB图像有255255255的N次方种变化。也就是说同样尺寸的图像,二值图保存的信息更少。二值图像(binary image),即图像上的每一个像素只有两种可能的取值或灰度等级状态,人们经常用黑白、B&W、单色图像表示二值图像。

(五)、图像算数操作
1、图像加法
可以用cv2.add()函数对两个图像进行相加操作,也可以用NumPy:res = img1 + img2。相加的两个图片必须是同一类型,或有一个图片有一个channel。
2、图像融合
这也是图像的加法,但是它可以指定相加图像的权重,可以得到一个透明的效果。
3、图像位操作
位操作包括与(and)或(or)非(not)和异或(xor)。它在提取图像的任意部分,处理非长方形图像时很有用。
这里放一个博客,非常详细的写了图像算术操作的具体步骤以及代码
http://blog.topspeedsnail.com/archives/2098

四、练习numpy的中array的基本操作

为什么要用numpy

Python中提供了list容器,可以当作数组使用。但列表中的元素可以是任何对象,因此列表中保存的是对象的指针,这样一来,为了保存一个简单的列表[1,2,3]。就需要三个指针和三个整数对象。对于数值运算来说,这种结构显然不够高效。
Python虽然也提供了array模块,但其只支持一维数组,不支持多维数组(在TensorFlow里面偏向于矩阵理解),也没有各种运算函数。因而不适合数值运算。
NumPy的出现弥补了这些不足。

(——摘自张若愚的《Python科学计算》)

import numpy as np

以下放入的是python2的代码
(一)、数组创建

#常规创建方法
a = np.array([2,3,4])
b = np.array([2.0,3.0,4.0])
c = np.array([[1.0,2.0],[3.0,4.0]])
d = np.array([[1,2],[3,4]],dtype=complex) # 指定数据类型
print a, a.dtype)
print b, b.dtype)
print c, c.dtype
print d, d.dtype

[2 3 4] int32
[ 2.  3.  4.] float64
[[ 1.  2.]
 [ 3.  4.]] float64
[[ 1.+0.j  2.+0.j]
 [ 3.+0.j  4.+0.j]] complex128

(二)、数组的常用函数

print np.arange(0,7,1,dtype=np.int16) # 0为起点,间隔为1时可缺省(引起歧义下不可缺省)
print np.ones((2,3,4),dtype=np.int16) # 2页,3行,4列,全1,指定数据类型
print np.zeros((2,3,4)) # 2页,3行,4列,全0
print np.empty((2,3)) #值取决于内存
print np.arange(0,10,2) # 起点为0,不超过10,步长为2
print np.linspace(-1,2,5) # 起点为-1,终点为2,取5个点
print np.random.randint(0,3,(2,3)) # 大于等于0,小于3,2行3列的随机整数


[0 1 2 3 4 5 6]
[[[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]

 [[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]]
[[[ 0.  0.  0.  0.]
  [ 0.  0.  0.  0.]
  [ 0.  0.  0.  0.]]

 [[ 0.  0.  0.  0.]
  [ 0.  0.  0.  0.]
  [ 0.  0.  0.  0.]]]
[[  1.39069238e-309   1.39069238e-309   1.39069238e-309]
 [  1.39069238e-309   1.39069238e-309   1.39069238e-309]]
[0 2 4 6 8]
[-1.   -0.25  0.5   1.25  2.  ]
[[1 0 1]
 [0 1 0]]

(三)、类型转换

print float(1)
print int(1.0)
print bool(2)
print float(True)

  

1.0
1
True
1.0

(四)、数组输出

  print np.arange(1,6,2)
    print np.arange(12).reshape(3,4) # 可以改变输出形状
    print np.arange(24).reshape(2,3,4)# 2页,3行,4页


[1 3 5]
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

这里转载自
https://blog.csdn.net/qq_24193303/article/details/80965274
写的非常详细
也推荐学习numpy的中文文档,上面讲的很全
下面是链接
https://www.numpy.org.cn/index.html
numpy的练习题及答案
https://blog.csdn.net/qq_41996090/article/details/88558929

五、练习图像的加载,保存,以及算数操作

图像的加载,保存,以及算数操作在上文已显示过实现代码以及完成图了,就不在这里重复放代码了。

To be continued…

2018-10-17 11:10:21 ahilll 阅读数 5100

  最近一段时间学习并做的都是对图像进行处理,其实自己也是新手,各种尝试,所以我这个门外汉想总结一下自己学习的东西,图像处理的流程。但是动起笔来想总结,一下却不知道自己要写什么,那就把自己做过的相似图片搜索的流程整理一下,想到什么说什么吧。

  首先在进行图片灰度化处理之前,我觉得有必要了解一下为什么要进行灰度化处理。

图像灰度化的目的是什么?

  将彩色图像转化为灰度图像的过程是图像的灰度化处理。彩色图像中的每个像素的颜色由R,G,B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。而灰度图像是R,G,B三个分量相同的一种特殊的彩色图像,其中一个像素点的变化范围为255种,所以在数字图像处理中一般将各种格式的图像转化为灰度图像以使后续的图像的计算量少一些。灰度图像的描述与彩色图像一样仍然反映了整副图像的整体和局部的色度和高亮等级的分布和特征。

一:图像灰度化处理

  灰度化处理就是将一幅色彩图像转化为灰度图像的过程。彩色图像分为R,G,B三个分量,分别显示出红绿蓝等各种颜色,灰度化就是使彩色的R,G,B分量相等的过程。灰度值大的像素点比较亮(像素值最大为255,为白色),反之比较暗(像素最下为0,为黑色)。

1.1   图像灰度化的算法:

  1)最大值法:使转化后的R,G,B得值等于转化前3个值中最大的一个,即:R=G=B=max(R,G,B)。这种方法转换的灰度图亮度很高。
  2)平均值法:是转化后R,G,B的值为转化前R,G,B的平均值。即:R=G=B=(R+G+B)/3。这种方法产生的灰度图像比较柔和。
  3)加权平均值法:按照一定权值,对R,G,B的值加权平均,即:这里写图片描述分别为R,G,B的权值,取不同的值形成不同的灰度图像。由于人眼对绿色最为敏感,红色次之,对蓝色的敏感性最低,因此使将得到较易识别的灰度图像。一般时,得到的灰度图像效果最好。

1.2   代码实现(灰度化+二值化)

from PIL import Image

#  load a color image
im = Image.open('durant.jpg' )

#  convert to grey level image
Lim = im.convert('L' )
Lim.save('grey.jpg' )

#  setup a converting table with constant threshold
threshold = 185
table = []
for i in range(256):
    if i < threshold:
        table.append(0)
    else:
        table.append(1)

# convert to binary image by the table
bim = Lim.point(table, '1' )

bim.save('durant_grey.jpg' )

原图图片效果展示:

 

灰度化图片效果展示:

二值化图片效果展示:

 1.3 convert() 方法详解

  Convert()会根据传入参数的不同将图像变成不同的模式。PIL中有九种不同模式。分别为1,L,P,RGB,RGBA,CMYK,YCbCr,I,F。

    模式‘1’为二值图像,非黑即白。但是它每个像素用8个bit表示,
0表示黑,255表示白。

    模式‘L’为灰色图像它的每个像素用8个bit表示,0表示黑,
255表示白,其他数字表示不同的灰度。在PIL中,从模式“RGB”转
换为“L”模式是按照下面的公式转换的:
    L = R * 299/1000 + G * 587/1000+ B * 114/1000

    模式“P”为8位彩色图像,它的每个像素用8个bit表示,其对应的
彩色值是按照调色板查询出来的。

    模式“RGBA”为32位彩色图像,它的每个像素用32个bit表示,其
中24bit表示红色、绿色和蓝色三个通道,另外8bit表示alpha通道,
即透明通道。

    模式“CMYK”为32位彩色图像,它的每个像素用32个bit表示。模
式“CMYK”就是印刷四分色模式,它是彩色印刷时采用的一种套色模
式,利用色料的三原色混色原理,加上黑色油墨,共计四种颜色混合
叠加,形成所谓“全彩印刷”。

    模式“YCbCr”为24位彩色图像,它的每个像素用24个bit表示。
YCbCr其中Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分
量。人的肉眼对视频的Y分量更敏感,因此在通过对色度分量进行子
采样来减少色度分量后,肉眼将察觉不到的图像质量的变化。

    模式“RGB”转换为“YCbCr”的公式如下:
        Y= 0.257R+0.504G+0.098B+16
        Cb = -0.148R-0.291G+0.439B+128
        Cr = 0.439R-0.368G-0.071*B+128

    模式“I”为32位整型灰色图像,它的每个像素用32个bit表示,0表示黑,
255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式“RGB”
转换为“I”模式是按照下面的公式转换的:
    I = R * 299/1000 + G * 587/1000 + B * 114/1000

    模式“F”为32位浮点灰色图像,它的每个像素用32个bit表示,0表示黑,
255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式“RGB”转
换为“F”模式是按照下面的公式转换的:
    F = R * 299/1000+ G * 587/1000 + B * 114/1000    

 

二:Python图像增强

2.1 图片增强三大类别:点增强,空间增强,频域增强

  图像增强是图像模式识别中非常重要的图像预处理过程。图像增强的目的是通过对图像中的信息进行处理,使得有利于模式识别的信息得到增强,不利于模式识别的信息被抑制,扩大图像中不同物体特征之间的差别,为图像的信息提取及其识别奠定良好的基础。图像增强按实现方法不同可分为点增强、空域增强和频域增强。

点增强

  点增强主要指图像灰度变换和几何变换。图像的灰度变换也称为点运算、对比度增强或对比度拉伸,它是图像数字化软件和图像显示软件的重要组成部分。

  灰度变换是一种既简单又重要的技术,它能让用户改变图像数据占据的灰度范围。一幅输入图像经过灰度变换后将产生一幅新的输出图像,由输入像素点的灰度值决定相应的输出像素点的灰度值。灰度变换不会改变图像内的空间关系

  图像的几何变换是图像处理中的另一种基本变换。它通常包括图像的平移、图像的镜像变换、图像的缩放和图像的旋转。通过图像的几何变换可以实现图像的最基本的坐标变换及缩放功能。

空域增强

  图像的空间信息可以反映图像中物体的位置 、形状、大小等特征,而这些特征可以通过一定的物理模式来描述。例如,物体的边缘轮廓由于灰度值变化剧烈一般出现高频率特征,而一个比较平滑的物体内部由于灰度值比较均一则呈现低频率特征。因此,根据需要可以分别增强图像的高频和低频特征。对图像的高频增强可以突出物体的边缘轮廓,从而起到锐化图像的作用。例如,对于人脸的比对查询,就需要通过高频增强技术来突出五宫的轮廓。相应地,对图像的低频部分进行增强可以对图像进行平滑处理,一般用于图像的噪声消除。

频域增强

  图像的空域增强一般只是对数字图像进行局部增强,而图像的频域增强可以对图像进行全局增强。频域增强技术是在数字图像的频率域空间对图像进行滤波,因此需要将图像从空间域变换到频率域,一般通过傅里叶变换实现。在频率域空间的滤波与空域滤波一样可以通过卷积实现,因此傅里叶变换和和卷积理论是频域滤波技术的基础。

2.2  python图像增强的目的是什么?

  图像增强的主要目的有:改变图像的灰度等级,提高图像对比度,消除边缘和噪声,平滑图像;突出边缘或者线性地物,锐化图像;合成彩色图像;压缩图像数据量,突出主要信息等。

  图像增强的主要内容有:空间域增强、频率域增强、彩色增强、多图像代数运算、多光谱图像增强等。

  在图像分类任务中,图像数据增强一般是大多数人会采用的方法之一,这是由于深度学习对数据集的大小有一定的要求,若原始的数据集比较小,无法很好地满足网络模型的训练,从而影响模型的性能,而图像增强是对原始图像进行一定的处理以扩充数据集,能够在一定程度上提升模型的性能。

 

2.3  亮度,色度,对比度,锐度增强

from PIL import Image
from PIL import ImageEnhance
# 原始图像
image = Image.open('deal_with/A1.jpg')
image.show()

#亮度增强
enh_bri = ImageEnhance.Brightness(image)
brightness = 1.5
image_brightened = enh_bri.enhance(brightness)
image_brightened.show()
image_brightened.save("image_brightened.jpg")

#色度增强
enh_col = ImageEnhance.Color(image)
color = 1.5
image_colored = enh_col.enhance(color)
image_colored.show()
image_colored.save("image_colored.jpg")

#对比度增强
enh_con = ImageEnhance.Contrast(image)
contrast = 1.5
image_contrasted = enh_con.enhance(contrast)
image_contrasted.show()
image_contrasted.save("image_contrasted.jpg")

#锐度增强
enh_sha = ImageEnhance.Sharpness(image)
sharpness = 3.0
image_sharped = enh_sha.enhance(sharpness)
image_sharped.show()
image_sharped.save("image_sharped.jpg")

 原图:

 

亮度增强:

 

色度增强:

 

对比度增强:

 

锐度增强:

 2.4  对图像进行翻转Flipping

  对图像进行翻转是最流行的图像数据增强方法之一,这主要是由于翻转图像操作的代码简单,以及对于大多数问题而言,对图像进行翻转操作能够提升模型的性能。下面的模型可以看到人是朝右而不是朝左边。

 三:图片相似度算法(对像素求方差并比对)的学习

3.1 算法逻辑

3.1.1  缩放图片

  将需要处理的图片所放到指定尺寸,缩放后图片大小由图片的信息量和复杂度决定。譬如,一些简单的图标之类图像包含的信息量少,复杂度低,可以缩放小一点。风景等复杂场景信息量大,复杂度高就不能缩放太小,容易丢失重要信息。根据自己需求,弹性的缩放。在效率和准确度之间维持平衡。

3.1.2  灰度处理

  通常对比图像相似度和颜色关系不是很大,所以处理为灰度图,减少后期计算的复杂度。如果有特殊需求则保留图像色彩。

3.1.3 计算平均值

  此处开始,与传统的哈希算法不同:分别依次计算图像每行像素点的平均值,记录每行像素点的平均值。每一个平均值对应着一行的特征。

3.1.4  计算方差

  对得到的所有平均值进行计算方差,得到的方差就是图像的特征值。方差可以很好的反应每行像素特征的波动,既记录了图片的主要信息。

3.1.5  比较方差

  经过上面的计算之后,每张图都会生成一个特征值(方差)。到此,比较图像相似度就是比较图像生成方差的接近成程度。
  一组数据方差的大小可以判断稳定性,多组数据方差的接近程度可以反应数据波动的接近程度。我们不关注方差的大小,只关注两个方差的差值的大小。方差差值越小图像越相似!

 

3.2  代码:

import cv2
import matplotlib.pyplot as plt

#计算方差
def getss(list):
    #计算平均值
    avg=sum(list)/len(list)
    #定义方差变量ss,初值为0
    ss=0
    #计算方差
    for l in list:
        ss+=(l-avg)*(l-avg)/len(list)
    #返回方差
    return ss

#获取每行像素平均值
def getdiff(img):
    #定义边长
    Sidelength=30
    #缩放图像
    img=cv2.resize(img,(Sidelength,Sidelength),interpolation=cv2.INTER_CUBIC)
    #灰度处理
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #avglist列表保存每行像素平均值
    avglist=[]
    #计算每行均值,保存到avglist列表
    for i in range(Sidelength):
        avg=sum(gray[i])/len(gray[i])
        avglist.append(avg)
    #返回avglist平均值
    return avglist

#读取测试图片
img1=cv2.imread("james.jpg")
diff1=getdiff(img1)
print('img1:',getss(diff1))

#读取测试图片
img11=cv2.imread("durant.jpg")
diff11=getdiff(img11)
print('img11:',getss(diff11))

ss1=getss(diff1)
ss2=getss(diff11)
print("两张照片的方差为:%s"%(abs(ss1-ss2)))

x=range(30)

plt.figure("avg")
plt.plot(x,diff1,marker="*",label="$jiames$")
plt.plot(x,diff11,marker="*",label="$durant$")
plt.title("avg")
plt.legend()
plt.show()


cv2.waitKey(0)
cv2.destroyAllWindows()

 两张原图:

 

图像结果如下:

img1: 357.03162469135805
img11: 202.56193703703704
两张照片的方差为:154.469687654321

 

   实验环境开始设置了图片像素值,而且进行灰度化处理,此方法比对图像相似对不同的图片方差很大,结果很明显,但是对比比较相似,特别相似的图片不适应。

四:图片相似度算法(感知哈希算法)的学习

  "感知哈希算法"(Perceptual hash algorithm),它的作用是对每张图片生成一个"指纹"(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。

4.1  算法步骤

4.1.1 缩小尺寸

  将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。

4.1.2  简化色彩

  将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。

4.1.3  计算平均值

  计算所有64个像素的灰度平均值

4.1.4  比较像素的灰度平均值

  将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。

4.1.5 计算哈希值

  将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

  得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算"汉明距离"(Hamming distance)。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。

    此算法参考博客:http://www.ruanyifeng.com/blog/2011/07
    /principle_of_similar_image_search.html
    
但是未实现代码,代码如下:

 

#!/usr/bin/python

import glob
import os
import sys

from PIL import Image

EXTS = 'jpg', 'jpeg', 'JPG', 'JPEG', 'gif', 'GIF', 'png', 'PNG'

def avhash(im):
    if not isinstance(im, Image.Image):
        im = Image.open(im)
    im = im.resize((8, 8), Image.ANTIALIAS).convert('L')
    avg = reduce(lambda x, y: x + y, im.getdata()) / 64.
    return reduce(lambda x, (y, z): x | (z << y),
                  enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())),
                  0)

def hamming(h1, h2):
    h, d = 0, h1 ^ h2
    while d:
        h += 1
        d &= d - 1
    return h

if __name__ == '__main__':
    if len(sys.argv) <= 1 or len(sys.argv) > 3:
        print "Usage: %s image.jpg [dir]" % sys.argv[0]
    else:
        im, wd = sys.argv[1], '.' if len(sys.argv) < 3 else sys.argv[2]
        h = avhash(im)

        os.chdir(wd)
        images = []
        for ext in EXTS:
            images.extend(glob.glob('*.%s' % ext))

        seq = []
        prog = int(len(images) > 50 and sys.stdout.isatty())
        for f in images:
            seq.append((f, hamming(avhash(f), h)))
            if prog:
                perc = 100. * prog / len(images)
                x = int(2 * perc / 5)
                print '\rCalculating... [' + '#' * x + ' ' * (40 - x) + ']',
                print '%.2f%%' % perc, '(%d/%d)' % (prog, len(images)),
                sys.stdout.flush()
                prog += 1

        if prog: print
        for f, ham in sorted(seq, key=lambda i: i[1]):
            print "%d\t%s" % (ham, f)

 

五:marking——对OpenCV中cvWaitKey函数的学习

  用OpenCV来显示图像或者视频时,如果后面不加cvWaitKey这个函数,基本上是显示不出来的。

  显示图像,一般要在cvShowImage()函数后面加一句cvWaitKey(0);否则图像无法正常显示。

  

def waitKey(delay=None): # real signature unknown; restored from __doc__
    """
    waitKey([, delay]) -> retval
    .   @brief Waits for a pressed key.
    .   
    .   The function waitKey waits for a key event infinitely (when \f$\texttt{delay}\leq 0\f$ ) or for delay
    .   milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the
    .   function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is
    .   running on your computer at that time. It returns the code of the pressed key or -1 if no key was
    .   pressed before the specified time had elapsed.
    .   
    .   @note
    .   
    .   This function is the only method in HighGUI that can fetch and handle events, so it needs to be
    .   called periodically for normal event processing unless HighGUI is used within an environment that
    .   takes care of event processing.
    .   
    .   @note
    .   
    .   The function only works if there is at least one HighGUI window created and the window is active.
    .   If there are several HighGUI windows, any of them can be active.
    .   
    .   @param delay Delay in milliseconds. 0 is the special value that means "forever".
    """
    pass

 

 

六:marking——图像增强中一阶微分和二阶微分的区别

1,斜坡面上,一阶微分一直不为0 ;二阶微分只有终点和起点不为0

2,一阶微分产生较粗的边缘,二阶微分则细得多

3,一阶微分处理一般对灰度阶梯有较强的响应;二阶微分处理细节有较强的响应

 

七:关于OpenCV

  OpenCV的全称open Sourse Computer Vision Library ,是一个跨平台的计算机视觉库,OpenCV可用于开发实时的图像处理,计算机视觉以及模式识别的程序。

  OpenCV是用C++语言编写,它的主要接口也是C++语言,但是依然保留了大量的C语言接口,该库也有大量的Python,Java和MATLAB的接口,另外,一个使用CUDA的GPU接口也用于2010.9 开始实现。

7.1  为什么使用Python+OpenCV

  虽然python很强大,而且也有自己的图像处理库PIL,但是相对于OpenCV来讲,它还是弱小很多。跟很多开源软件一样OpenCV也提供了完善的python接口,非常便于调用。OpenCV 的稳定版是2.4.8,最新版是3.0,包含了超过2500个算法和函数,几乎任何一个能想到的成熟算法都可以通过调用OpenCV的函数来实现,超级方便。

 

 7.2  import cv2发生错误的解决方案

   错误如下:

1,进入cmd控制台,查看python版本

2 根据自己用的python版本,下载对应的OpenCV

https://www.lfd.uci.edu/~gohlke/pythonlibs/

 

 3,下载numpy,对应的版本

https://pypi.python.org/pypi/numpy 

 cp36代表着匹配python3.6版本。

win32、amd64代表着32位、64位系统。

  

4,安装OpenCV,下载下来是一个whl格式文件,把此文件放在安装的文件名下,直接安装。

 

  就这样安装成功。

 

 

参考文献:https://blog.csdn.net/wsp_1138886114/article/details/81368890

2015-07-29 10:52:41 qq_26898461 阅读数 16095

经历了半年多的学习,图像处理总算入门了,做了个小项目,将之前所学的都用到了。虽不敢说精通,但该掌握的工具都掌握了,包括图像算法。图像处理虽说不难,但刚开始入门,还是不易的,我也走了不少弯路,希望借鉴给有缘人。

首先,搞图像处理,熟悉图像算法是必经之路,如果上过图像处理这门课的话,再好不过。如果没有,我推荐中科院研究生院刘定生老师的数字图像处理与分析(视频),这位老师上课引人入胜,值得推荐。其次,在这个阶段,配套的书籍自然是《冈萨雷斯版数字图像处理》这本书,最好同时用matlab软件,仿真每一个图像算法案例,推荐《matlab宝典》。大概花一个月时间,基本的图像算法,相信你已经学完了。第二阶段,希望你再次认真学习C++,推荐《C++ Primer》,因为以后我们开发程序,都是基于类的开发,什么虚函数,类的继承、多态、命名空间、文件的输入输出、模板STL都应非常熟悉。在这之后,VC++你也应该掌握,圣经级的书籍自然是孙鑫的《VC++深入详解》,大概花一个时间,将书上每一个代码都敲一边,消息的映射机制,尤其要非常熟悉,MFC的框架结构也应明白。在此阶段,有时间的话,看看中科院研究生院杨力祥老师的高级windows程序设计(视频),这些代码开发都是基于VC6.0的。

以上如果你都搞明白了,就进入重头戏了。将图像处理算法和代码结合起来,进行开发。首推北航老师谢凤英, 赵主培主编的《Visual C++数字图像处理》这本书,将上面的代码都敲一边,你会有不一样的感觉。

最后一个阶段,因为在实际的开发过程中,不可能每一基本算法都要自己写,前人已经写好了。所以推荐大家使用opencv这个开源库,他实现了大多数图像算法,实际开发中,用他的函数就够了,推荐书籍《学习opencv》,《opencv教程》,视频自然是庞峰老师的视频,大家可以在opencv中文论坛上免费观看。至此,该掌握的工具你已经掌握了,但是将MFC和opencv结合起来开发,最好是要有一个项目,你会理解许多。

最后,我想说MFC开发已经过时了(俗称没饭吃),但是他的那套消息机制还是非常有用的,建议大家界面开发的用C#或QT,代码编写结合opencv,这样你会轻松很多。在图像处理领域中,真正得到大牛都是搞算法的,建议大家在看看计算机视觉和模式识别、机器学习方面的书籍。至此,以上就是我的感悟。

2020-06-17 11:17:03 kukerander 阅读数 24

深度相机介绍

目前的深度相机根据其工作原理可以分为三种:TOF、RGB双目、结构光

一、RGB双目

    RGB双目相机因为非常依赖纯图像特征匹配,所以在光照较暗或者过度曝光的情况下效果都非常差,另外如果被测场景本身缺乏纹理,也很难进行特征提取和匹配你看看下面的图就懂了。


三种相机的参数对比:

从分辨率、帧率、软件复杂度、功耗等方面来考虑

(1)分辨率

    TOF方案深度图分辨率很难提高,一般都达不到VGA(640x480)分辨率。比如Kinect2的TOF方案深度图分辨率只有512x424。而Google和联想合作的PHAB2手机的后置TOF深度相机分辨率只有224x171。TOF方案受物理器件的限制,分辨率很难做到接近VGA的,即使做到,也会和功耗呈指数倍增长。

    结构光的分辨率在较近使用范围内,结构光方案的分辨率会大大高于TOF方案。比如目前结构光方案的深度图最高可以做到1080p左右的分辨率了。
(2)帧率

    帧率的话,TOF方案可以达到非常高的帧率,差不多上百fps吧。结构光方案帧率会低点,典型的是30fps,不过这也基本够用了。

(3)软件复杂度

    结构光因为需要对编码的结构光进行解码,所以复杂度要比直接测距的TOF高一些。

(4)功耗

    TOF是激光全面照射,而结构光是只照射其中局部区域,比如PrimeSense的伪随机散斑图案,只覆盖了不到十分之一的空间。另外,TOF发射的是高频调制脉冲,而结构光投射图案并不需要高频调制,所以结构光的功耗要比TOF低很多。还是以伪随机散斑结构光为例,结构光方案功耗只有TOF的十分之一不到吧。

    下面是三种方案在分辨率,帧率,软件复杂度和功耗方面的对比结果。

    结构光方案还有一个优势在于技术成熟,PrimeSense很早就把结构光技术用在kinect一代产品中了。目前结构光技术有如下几种变种:一种是单目IR+投影红外点阵,另外一种是双目IR+投影红外点阵,这样相当于结构光+双目立体融合了,深度测量效果会比前者好一些,比如Intel RealSense R200采用的就是双目IR+投影红外点阵,不足之处就是体积较大。而单目IR+投影红外点阵的方案虽然体积较小,但是效果会差一点。
(5)计算复杂度

    计算方式也分几种:一是直接用ASIC(专用集成电路)进行计算,成本稍微高一点,但是处理速度快,支持高帧率和高分辨率深度相机,关键是比通用芯片功耗低。二是DSP+软件算法,成本跟用ASIC差不多,但支持不了高帧率高分辨率,功耗比ASIC稍高。三是直接用手机的AP(Application Processor)进行纯软件计算,这个不需要额外增加硬件成本,但是比较消耗AP的计算资源。同样也不支持高帧率高分辨率,功耗比较大。

  
  iPhone X的深度相机技术方案:结构光原理的深度相机。具体来说是:单目IR+投影红外点阵+ASIC方案。该方案在深度分辨率、深度测量精度上有较大优势,实时性处理和全天候工作也都有保障,功耗也相对较低,就是成本稍高了一些。

    9月13日苹果发布了致敬十周年的新机型iPhone X,其中前置原深感(TrueDepth)相机引起了极大的舆论关注。该相机的构成如下图所示。从左到右,依次是红外镜头、泛光感应元件、距离传感器、环境光传感器、扬声器、麦克风、700万像素摄像头、点阵投影器。其中最有里程碑意义的当属红外镜头 + 点阵投影器 + RGB摄像头的组合。

转自:https://blog.csdn.net/electech6/article/details/78889057
https://blog.csdn.net/electech6/article/details/78348917

图像处理之深度学习

阅读数 12196

学习图像处理

阅读数 71