用Python+OpenCV进行图像处理基本操作

引言

用python进行处理图像,我一开始是使用的PIL库,不过目前看来我需要要转到openCV上了,因为涉及到一些图形处理的算法上,PIL库还是太简单了。openCV作为研究计算机视觉、机器学习等算法的首选库,学会使它对我目前的图像处理的学习还是非常有必要的。

OpenCV库的安装

由于openCV是一种支持多平台多语言的库,所以其安装是非常简单的,直接到官网上下载对应操作系统的安装包安装即可。

由于我这里是要在python中对其进行调用,在windows下还需要另外一步操作:

opencv/build/python/2.7/x64/目录下的 cv2.pyd文件(当然如果你的操作系统是32bit的目录则为 opencv/build/python/2.7/x86/),复制到python的安装目录的 Lib/site-packages/子目录中。

在python的命令行中测试import cv2,无错误则表示python对openCV库调用成功。

不过要注意的是:

  • 安装的openCV版本需要支持你安装的python的版本
  • 需要numpy的支持,所以openCV安装前要确保numpy安装好了
  • 推荐同时安装matplotlib库,提供多种图标的绘制,不过这个是可选的

Python中使用OpenCV的对图像的基本操作

官方的说明参考官方说明文档地址为:https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html

详细的使用直接看官方文档,我这里这里只是通过阅读官方文档,整理一些最基本的使用方法和注意事项。

  1. 读取图片

    使用openCV先需要导入库

    1
    import cv2

    使用imread()函数读取不同格式的图像,返回值numpy.ndarray类型的数据

    1
    img = cv2.imread('messi5.jpg')
  2. 显示图片

    使用imshow()函数创建一个窗口来显示图片

    1
    2
    3
    cv2.imshow('image',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    注意点:

    • cv2.imshow()函数第一参数为窗口的名字,第二参数是需要显示的图片。函数可以创建多个窗口,并同时显示,但是窗口名不同相同。
    • cv2.waitKey()函数是等待案件消息处理函数,出窗口的消息。
    • cv2.destroyAllWindows()销毁所有窗口
  3. 保存图片

    使用imwrite()函数写入保存图片

    1
    cv2.imwrite('messigray.png',img)
  4. 使用matplotlib画图

    显示用灰色模式图片

    1
    2
    3
    4
    5
    import cv2  
    import matplotlib.pyplot as plt
    img = cv2.imread("chengbao.jpg",0)
    plt.imshow(img, cmap = 'gray')
    plt.show()

    上面代码是显示灰色模式的图片,但是如果是彩色模式的话,要注意一个问题:

    OpenCV的色彩模式是BGR模式,而Matplotlib的显示模式是RGB所示,直接OpenCV导入的图片用Matplotlib显示是不能正确显示的。如果需要正确显示的话要将BGR模式转化为RGB模式。处理方法参考stackoverflow上的帖子

  5. 访问和修改pixel Rawdata

    cv2.imread()函数的返回值即使图像的Rawdata,是numpy.darray类型的数据。通过这个返回值可以操作图像的原始数据,所以对Rawdata的操作都只要用到numpy的方法就可以了,不管是点操作或者区域操作。

  6. 创建边框

    使用cv2.copyMakeBorder()函数创建边框

    1
    constant = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTAN,value=[255,0,0])

    结果对比如下图:

    无border
    加border

Compartir

用Python实现图像直方图的均衡和匹配

需要使用的库

以下为使用Python来实现图像直方图均衡和匹配中需要用到的库

  • PIL: 用于导入图片、修改图片、显示图片
  • numpy:用于接收图像rawdata,方便处理多维数据数据
  • matplotlib:用于画直方图、显示图像

Python推荐安装anaconda整合包,包括numpy在内的很多库已经安装好了。没有安装的库推荐用pip安装,这样可以不用考虑库之间的烦人的依赖关系。

以下源码均为自己实现

画直方图

使用matplotlib库中的 hist函数画直方图,步骤图下:

  1. 打开图像
  2. 导入图像的Rawdata
  3. 用生成hist生成直方图

代码如下:

1
2
3
4
5
6
7
8
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

im = Image.open('chengbao.jpg')
buf = np.array(im)
plt.hist(buf.flatten(), 256, normed = True)
plt.show()

使用测试图像如下:

图1 测试图像

运行程序生成直方图如下:

图2 测试图像的直方图

实现直方图均衡化

图像直方图的均衡属于图像的点操作,直接用PIL库中的 point函数即可,point函数可以对图像中的每一个点都进行相同的处理,并返回一个新的图像。

直方图均衡的公式如下:

f(s) = Sum(P(0:s)) x (L-1)


用python一句话就可以实现。

于是可以在上面的代码的后面加入均衡化的功能:

1
2
3
4
5
6
dhist, bins_edge = np.histogram(buf.flatten(), 256, density = True) # 也可以直接接收上面hist函数的返回值
outIm = im.point(lambda i: sum(dhist[:i])*255)
outIm.show()

plt.hist(np.array(outIm).flatten(), 256, normed = True)
plt.show()

均衡化后生成的图像如下:

图3 测试图像均衡化

均衡化后的直方图为:

图4 测试图像均衡化的直方图

可以看到这幅图像在均衡化后,之前朦胧的地方变得更清晰了,但是其噪声也增多了和颗粒感也更严重了。

实现直方图匹配

虽然直方图的匹配会稍显复杂,但是并没有使用额外的知识点。只需要按照步骤一步一步实现代码就可以了。

所以我这里就直接贴全部代码,下面代码的目的是将原图像匹配到目标图像的直方图上,目标图像就是chengbao.jpg,其原始图像和直方图分布都上面(图1和图2):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# coding:utf8

from PIL import Image
import matplotlib.pyplot as plt

import numpy as np

def eqhist(histarray):
farr = np.zeros(256,dtype= np.uint16)
for i in range(256):
farr[i] = np.sum(histarray[:i])*255
if farr[i] > 255: farr[i] = 255
return farr

def main():
imlist = []
imlist.append(Image.open('chengbao.jpg'))
imlist.append(Image.open('target.jpg'))
srcIm = imlist[1]
targIm = imlist[0]
srcIm.show()
# targIm.show()

srcbuf = np.array(srcIm)
targbuf = np.array(targIm)

# 显示原始直方图
plt.subplot(2, 2, 1)
srchist, bins, patche = plt.hist(srcbuf.flatten(), 256, normed = True)
plt.subplot(2, 2, 3)
targhist, bins, patche = plt.hist(targbuf.flatten(), 256, normed = True)

# 先做直方图均衡
resSrchist = eqhist(srchist)
restarghist = eqhist(targhist)

# 求匹配的映射关系序列
MapArray = np.zeros(256,dtype= np.uint8)
for x in xrange(256):
MapArray[restarghist[x]] = x

tmp = MapArray[0];
for x in xrange(1,256):
if MapArray[x] != 0:
tmp = MapArray[x]
else:
MapArray[x] = tmp

# 执行匹配
outIm = srcIm.point(lambda i: MapArray[resSrchist[i]])
plt.subplot(2, 2, 2)
plt.hist(np.array(outIm).flatten(), 256, normed = True)

outIm.show()
plt.show()


if __name__ == '__main__':
main()

执行结果如下:

图5 匹配的原始图像
图6 匹配的原始图像
图7 匹配前后图像直方图对比

图7 直方图对比中,左上为原始图像的直方图,左下为目标图像的直方图,右上为匹配后图像的直方图。可以看到匹配后的直方图和目标图像的直方图是非常相似的。

Compartir

图像与视频处理——直方图均衡和匹配

引言

这是《图像与视频处理》系列课程第三周的内容,由于第二周图像压缩部分难度较大,所以先跳过总结第三周的内容。第三周的内容主要是以直方图为基础展开的,重点是直方图的 均衡匹配。在这篇文章中,我只写对这些概念的理解,实际的使用再另外写。

直方图

对于数字图像而言,直方图是统计图像明暗灰度值像素点数的分布的图像,一般横轴的范围为0~255(因为目前图像灰度的量化等级一般为256),表示图像的不同灰度的量化值,纵轴表示在该亮度值下或区间内有的像素点的个数或占总数的比例。

从图像的直方图上我们可以很直观的得到图像的明暗分布信息,检查图像是否过曝或者欠曝,图像明暗是否分布均衡等等。

如下图,上面的图像就欠曝了,高光的像素点几乎没有;下面的图像整体分布还比较好,但是几乎没有暗部细节:

直方图

直方图均衡化

直方图的均衡化是将那些明暗分布不均匀的图像转换为均匀分布的一种方法,图下图所示,理想情况下直方图均衡化能将原分布转换为水平的直线分布,这表示图像上所有灰度值出现的几率都是一样的。当然由于量化的存在,实际上是达不到理想效果的。

理想的直方图均衡化

要达到如上图的效果,则需要找到一个转换关系式,该转换关系需要有如下特性:

  • 理想情况的最大值为L-1,最小值为0
  • 是严格单调递增的函数,因为希望原图像中亮的像素点转换后在新图像中仍然是亮的点,而不希望被反过来

直方图均衡化转化关系如下:

f(s) = Sum(P(0:s)) x (L-1)


在上式中P(s)为灰度值为s时的像素点占总数的比例,Sum(P(0:s))表示从P(0)到P(s)的累加和,L为常数,表示转换后图像灰度值的上限,一般都是256

直方图匹配

直方图匹配和直方图的均衡都可以是认为是一种直方图的转换,通过某种转换关系,能够将原的直方图的图像映射为目标直方图的图像。不过直方图匹配是对直方图的一种扩展,因为直方图均衡化的目标直方图是非常特殊的并行与横轴的直线,而直方图的匹配的目标直方图则是任意给定的。

由于目标直方图是任意的,所以要直接求出原图像直方图和目标直方图的映射关系式是很困难的,所以得到一个简单易用的方法,我们借助了直方图的均衡化来见解获得。

具体思路如下(F1(m)为原图像的直方图,F2(m)为目标直方图,g(s)为均衡化的直方图):

Rry:

F1(m) ----> F2(n)   


is Hard, So:

F1(x1) ----> g(s1)
F2(x2) ----> g(s2)
s1 ----> s2
g(s1) ----> F2(x1) 


(以上箭头都表示通过某种映射)

Compartir

用Scrapy框架做网页爬虫

前言

一直以来都非常想做一个网页爬虫,用来自动收集归档网页端的数据和一些有用的信息。前面尝试过自己完全用python实现,但是由于对这些东西并不熟悉,所以写得太差,毫无实用性可言。这也是工作中一直使用C++遗留下来的坏习惯——什么东西都想自己写,虽然早就明白“不要重复制造轮子”。

于是前几天就开始寻找开源的网页爬虫框架,网上有人统计排名前50的开源爬虫框架http://www.open-open.com/lib/view/open1422112155796.html,于是我就选择了排名比较靠前且与python更相近的Scrapy。

Scrapy的介绍

由于我自己是刚刚接触Scrapy,它的一些特性我是完全不知道,所以在这里我只能是引用百科里的介绍了(不用说明出处了,因为各大中文百科介绍都一个样):

Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点
并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化
测试。 Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。
它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了
web2.0爬虫的支持。


Scrapy的安装

由于Scrapy是用python开发的,所以安装Scrapy前python的环境需要安装好是必须的。具体安装说明参考官方的文档的Installation guide部分。

由于我的机器有安装pip工具,所以我直接用pip安装:

pip install Scrapy


Scrapy的初步使用

  1. 创建Scrapy工程目录

    在命令行界面下输入如下命令(创建根目录名为tutorial):

    scrapy startproject tutorial
    
    
    

    生成目录结构如下:

    tutorial/
        scrapy.cfg            # deploy configuration file
        tutorial/             # project's Python module, you'll import your code from here
            __init__.py
            items.py          # project items file
            pipelines.py      # project pipelines file
            settings.py       # project settings file
            spiders/          # a directory where you'll later put your spiders
                __init__.py
                ...
    
    
  2. 编写spider类

    在tutorial/spiders目录中创建myspider.py(文件名随意)

    引用官方文档的参考代码,地址:http://doc.scrapy.org/en/latest/intro/tutorial.html(由于dmoz网站的代码有更新,所以例子中的代码现在是获取不了需要的数据的):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import scrapy

    from tutorial.items import DmozItem

    class DmozSpider(scrapy.Spider):
    name = "dmoz"
    allowed_domains = ["dmoz.org"]
    start_urls = [
    "http://www.dmoz.org/Computers/Programming/Languages/Python/",
    ]

    def parse(self, response):
    for href in response.css("ul.directory.dir-col > li > a::attr('href')"):
    url = response.urljoin(href.extract())
    yield scrapy.Request(url, callback=self.parse_dir_contents)

    def parse_dir_contents(self, response):
    for sel in response.xpath('//ul/li'):
    item = DmozItem()
    item['title'] = sel.xpath('a/text()').extract()
    item['link'] = sel.xpath('a/@href').extract()
    item['desc'] = sel.xpath('text()').extract()
    yield item

    修改item.py中的代码:

    1
    2
    3
    4
    5
    6
    import scrapy

    class DmozItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()
    desc = scrapy.Field()

    DmozSpider类需要继承于scrapy.Spider类,名字随意定。DmozSpider中name需要唯一,表示爬虫的名字。start_urls是起始网页列表,爬虫从这些网页开始爬行。

    爬虫开始后会为start_urls列表中每一条url创建一个scrapy.Request对象,而它将parse函数作为其回调函数。在这个列子中parse函数的作用是解析页面中的需要爬的url。而parse_dir_contents函数的作用是解析出页面的数据。

    解析的数据用DmozItem记录。

  3. 启动爬虫

    以上面的例子,使用如下命令启动爬虫,”dmoz”便是前面DmozSpider类中定义的name:

    scrapy crawl dmoz
    
    
    

    将数据输出在json文件中:

    scrapy crawl dmoz -o items.json
    
    
    

XPath的使用

要获取页面中的数据,必然需要定位HTML文档中的节点。Scrapy将自己的机制称之为selectors,通过 XPath 和 CSS expression的两种方法定位。

由于XPath是使用得更为广泛,所以我主要使用XPath表达式来地位网页中的元素节点。在w3c的网站上有详细的XPath的教程:http://www.w3school.com.cn/xpath/index.asp

我这里说明一些注意点:

  1. 只有用”//“定位时才可以省略其前面的先辈节点,其他的需要一层一层的定位。
  2. “@”符号用于指定节点的属性,用法如:’//div[@id=”not-exists”]/text()’
Compartir

用Python对图像进行简单的操作(利用PIL库)

用Python来处理图像的原因

《图像与视频处理》这门课程的实验都是用Matlab去实现的,不过鉴于我自己对Python更熟悉一些,而且Python中也有专门对图像操作的库,所以我希望我能用Python也能实现相同的功能。

PIL库

PIL(Python Imaging Library)是Python平台最常用的图像处理第三方库,支持多种图片格式。我主要使用PIL库中的Image模块来实现对图像的一些简单操作。

在windows平台上一般现在官方安装文件即可,但是由于官方的PIL库支持32位系统,所以64位的系统需要下载其他非官方编译的库的.whl文件(网址),将.whl文件放到本地,然后用pip安装。

PIL库Image模块使用

以前面的课程练习为例:通过对多幅连续拍照的图像累加,来消除噪点。

下面仅仅介绍本例中使用到的PIL库Image模块的基本方法,详细的说明参考官方文档

  1. 导入PIL的Image模块

    1
    from PIL import Image
  2. 打开和关闭图片

    1
    2
    im = Image.open(fileName)
    im = Image.close()
  3. 获取和设置pixel的Rawdata大小

    1
    2
    rawdata = im.getdata()
    im.putdata(rawdata)
  4. 显示和保存图像

    1
    2
    im.show()
    im.save('image.jpg')

通过以上的方法,就可以通过PIL库的Image模块操作图片了:

打开图片-->获取图像原始数据-->改变图像原始数据-->保存图像-->关闭图像


使用以上方法的体验

  1. 打开图像速度快

    由于open的操作默认是不进行Load操作的,所以用open()函数打开图像时,速度是比较快的。

  2. 图像数据为3种颜色通道的3维矩阵,转换为numpy的array处理比较方便

    为了对图像实现加法操作,我需要将获取解码后的图像的原始rawdata,在累加完成求取平均值之后,再将其编码放回去。

    getdata函数的返回值类型是 ImagingCore类型,是PIL内部类型,为了方便我外部使用,我们最容易想到的是事是转化为numpy的array,来做矩阵数据计算时最方便的。为了转换为numpy的array可以用以下两种方法:

    1
    dataArray = np.array(list(im.getdata()))

    or

    1
    dataArray = np.array(im.getdata()))

    表面上看第二种要简洁,但是实际运行时间,反而第二种方法比第一种时间要长,有点搞不懂。

  3. putdata函数使用不是很方便

    oupdata函数需要的参数类型为 tupleImagingCore,当我们用numpy的array处理完数据后,还需要将数据转为 tuple,可以用下面的方法转化:

    1
    tupledat = tuple(map(tuple,avgdata))

    但是这个转化比较费时,我的机器处理一个1366 x 768像素大小的图像,需要花费几乎1.4s的时长,当需要处理的图像多了后就有点不合算了。

  4. 当处理大图片时 内存会炸掉

    用这种方法需要将图片数据全部读入内存,这样导致过大的图片就肯定是无法处理的。我尝试处理过用该方法去2352 x 4160大小的图片,结果机器剩余的1.5G内存几乎全部占完,而且处理速度也是慢的不行。

优化:(2016-7-25 后面才发现以下方法更高效方便,前面的方法慢成渣)

  • nunpy导入数据直接用Iamge对象:

    1
    dataArray = np.array(Image.open(fileName)))
  • 将nunpy的矩阵数据用fromarray()函数直接转换为Image对象:

    1
    im = Image.fromarray(rawdata))

    注意fromarray函数要求rawdata中的元素需要为np.uint8的类型,不是的用astype()函数来转换。

  • 可以用matplotlib.pyplot模块来显示图像:

    1
    2
    3
    import matplotlib.pyplot as plt
    plt.imshow(im2)
    plt.show()
Compartir

图像与视频处理——图像的基本操作

引言

图像的简单基本操作是《图像与视频处理》的 第一章最后节课程,里面介绍了图象处理中一些最最简单的基本操作。虽然是最简单的基本操作,但是对于一些特殊的情况也是种非常快速方便的解决问题的方法,所以我决定利用这些操,对应设计成一些解决实际应用情况的习题来做,以来加深理解。

应用实例

应用1:累加去噪——利用图像的累加取平均值的操作

应用场景:连续拍摄的静止物体,图像中噪点较多的情况

原理:由于是连续拍摄的静止的物体,所以所有的照片要都应该是一样的。将这些照片累加后取平局,噪声由于是随机的,累加后将会被滤掉。

结果对比如下,上面为原始图像,下边为累加后的图像:

原始图像 处理后的图像

可以看到,下面的图像经过多个图像累加后,噪声会小一些。特别是后面的墙壁和窗体,不像上面的图像一样模糊。但是由于这个照片曝光严重不足,所以景观噪声会变小,但是细节仍然是不清晰的。

应用2: 模糊和马赛克操作——利用邻域平均的方法

应用场景:任意需要模糊的图像

原理:虽然有很多高级的模糊方法,不最简单的就是用邻居求平局值了

应用3: 图像的各种放缩变形操作

应用场景:无

目的:只是为了练习这些方法的实现

Compartir

图像与视频处理——图像的采集

引言

图像采集时图像处理的基础,只有采集得到了图像数据后才能够进行图像处理的各种操作。

图像采集的原理

  • 主要器件——图像传感器

现在一般的数码相机的图像传感器都是将光信号转换为电信号,用矩形传感器阵列来生成投射到上面的图片。

  • 图像采集的过程——将拍摄实物离散化的过程

离散化是相机对真实实物的模拟,将这些真实实物转换为数字图像信息存储在计算机中。离散化有两方面的内容:

  1. 空间的离散化

    空间的离散化是将三位物体的位置信息投射到相机的传感器平面上,转换为数字二维坐标信息。

  2. 灰度的离散化

    灰度的离散化是对图像上色彩亮度的量化。实际上离散后的灰度值即包括的物体自身的颜色信息,有能够体现空间的深度信息,所以我们采集得到图像虽然是二维的,但是却又三维的感觉

  • 颜色的生成——红绿蓝三原色混合而成

数码相机的传感器有三种类型的传感器,分别来采集红绿蓝三种颜色的灰度。所以一副彩色的图像是由三幅不同颜色通道的灰度图像组成。

而实际大多数中低端的数码相机,都没有完整的三种类型的传感器,而是这三种类型的传感器间隔排列的,通过插值法来得到完整的三种颜色通道的灰度图像。

图像的存储

仅仅算图像的原始数据,1符图像需要的存储空间是=空间信息x颜色信息:

坐标空间信息需要: N x M bit,其中N、M表示图像长宽的像素点数
颜色信息: 3 x C bit, 其中C表示每种颜色需要的bit位数

如果是视屏还要算上时间信息和帧率。

Compartir

图像与视频处理——人体视觉系统(human visual system)

引言

人体视觉系统(human visual system)是《Image and Vidio Processing》课程中最先介绍的内容,可以算作为这门课程的背景知识。在课程的视屏教程中仅仅用了不到20分钟的时间就完成了这部份的内容,但是实际上要深入理解人体视觉系统是远不止如此的。

尽管在这门课程只是作为背景知识来介绍,但是这部分却是我在第一次学习中印象最深的内容。它给带来的作用并不仅仅是加深对这门课程的理解,更是直接向我解释了现实生活中那些曾经让我困惑的一些视觉问题,对我理解摄影技术提供极大的帮助。

人体视觉系统组成

人体视觉系统的组成是很复杂的,站在本课程的角度我无法也没有必要从生物学上系统学习学习,所以这里仅仅关注其组成的关键器官及关键部位——眼睛和视网膜上的两种视觉细胞

如下图是我在课程的视屏中截下的人眼简单的构造图:

人眼视觉组成

红色标记的是视网膜Retina,绿色部分都是属于视网膜区域。在视网膜上布满了是视觉细胞,外面的光线经过晶状体投射到视网膜上,由视网膜上的视觉细胞感应光信号。

在这里视网膜上的视觉细胞就作为光线传感器的作用,它们可以分为两类:

  1. cones(圆锥细胞)

    cones集中在视网膜的中心地方,在上图中就是fovca的地方,中心区外分布很少。cones擅长分辨物体细节,对光线有很大的灵敏度。

    另外cones除了能感受光强外,还能感受颜色。

  2. rods(杆状细胞)

    rods在视网膜上分布较广,它不能感受颜色,不擅长区分细节,但是擅长感受景物的轮廓,且在微光下表现良好。

这两种细胞相互补充,协同工作。理解产生人体视觉的这两类细胞的各自的特点,是非常重要的,能够帮助我们解释很多生活中的视觉现象。如:

  • 由于cones只集中在视网膜中心部位,所以为看清物体,人总是需要调整的眼睛位置移动眼珠,使被关注的物体能够投射到视网膜的中心
  • 暗光下能够能够看清物体缺区分不了颜色,因为暗光下的视觉成相主要是rods的作用

我们后面图像处理很多都是将人眼不能区分或是难以区分的图像处理到满足人眼视觉特性使人眼更容易感知的图片。

人体的视觉特性

  • 人眼对光的适应范围

人眼对光线的适应范围应该分两个角度来看:一面是光波的波长或频率,第二是光的强度。

  1. 光波的波长或频率

    在电磁波中,人眼能识别的部分被称为可见光,可见光在波长在整个光谱中只是很小的一部分,一般人眼识别的波长范围在400~760nm之间。如下图为我在Wiki中找到的电磁波频谱图,可以看到人眼能识别的部分非常小:

    电磁波的频谱图

    尽管人眼识别的可见光在光谱中很小,但是实际上利用其他感光传感器是可以采集到更广范围的光线的,并将这些光线生成图像。另外通过这些传感器生成的图像数据转换到可见光的范围内,就可以形成人眼可见的图像了。

  2. 光的强度

    过强或过弱的光线,会超出人眼的识别范围而导致无法识别物体。不过相对来说人眼能够识别的光强范围还是比较广的,但是这个广的适应范围是靠人眼的 动态调节来实现的。

    人眼的动态调节,是指人体的视觉系统会根据环境的光强,来改变视觉细胞的灵敏度,从而能够更好的观察物体的细节。所以我们是不能在既有情况又有弱光的环境中同时看清强光部分和弱光部分的细节。

    动态调节是需要时间的,所以当我们从忽然从黑暗的环境走到很亮的环境中,或者从很亮的环境中走到黑暗的环境中的时候,我们总是需要花上一点点时间才能看清周围的东西。

    从这点来看,现在相机和人体的视觉系统是很相似的地方的。实际我自己的感觉是相机在同一时刻能够适应的光强范围比人眼更差。特别是当我们拍摄光强差异较大的环境的时候,高光部分就饱和,暗光部分就一片黑。

    相机为了适应更广的光强范围(不在同一时刻),可以通过改变光圈大小或快门时间来调节相机的曝光补偿。而现在的大多数相机都有自动挡,通过检测所拍摄环境的光线,来自动调节曝光补偿参数。

  • 韦伯法则——人眼对高光区域有更好的灵敏度

    韦伯法则是用来说明人眼对光强改变灵敏程度的。它告诉我们,人眼对光线改变的敏感程度是非线性的。在明亮的环境下,小的光强改变都可以被人眼感受到;但是在昏暗的环境中,则需要光强有更大的改变才能被人察觉。

    实际上从上面人体视觉的两种视觉细胞的特点就可以反应这一点点现象,cones具有高敏感度、高分辨率,但那时需要比较明亮的条件下才能正常工作,所以亮光下,人眼的分辨率会更高。

    所以从图像来看也是这样的,如果我们希望我们的眼睛能够更清除的区分图像的细节,我们需要把照片调亮,这样对我们观察会更有利。

  • 马赫带——人眼对物体轮廓的强调

    这是1868年奥地利物理学家 E. 马赫发现的一种明度对比的视觉效应。是一种主观的边缘对比效应。当观察两块亮度不同的区域时,边界处亮度对比加强,使轮廓表现得特别明显。

    通俗的讲究是明暗交接处,暗的一边在人眼看来会更暗,亮的那一边在人眼看来会更亮。

  • 其他的一些视觉错觉现象

    如下图,亮度一样的方块,放在不同的环境中人会亮度是不同的:

    人眼对亮度的判断与环境有关

    再如下面这些图,体现了人眼有补全轮廓趋势、易受环境误导的现象:

    视觉错觉现象

Compartir

图像与视屏处理——前言

图像与视屏处理为Coursera上杜克大学提供的MOOC课程,原名为: 《Image and Vidio Processing: From Mars to Hollywood with a stop at Hospital》。课程时间较长,一共9周,内容也很系统、丰富,是学习图像处理的一个不错的选择。

但是由于很可惜,当时候我刚刚接触MOOC,完全没有考虑到了学习的难度,竟然在明知道个人时间有限的情况下同时报了两三课程。结果可想而知,随着课程的深入,学习起来越来越吃力,特别是《图像与视屏处理》这门课程,将所有的工作之余的时间都用上也只能很牵强的跟上课程的节奏。到后来工作开始变繁忙后,我也不得不放弃了这些课程,随着课程的结束,很多课程的页面也找不到了。

不过最近非常惊奇的发现,当初已经加入的那些课程的教学视屏用手机客户端中仍然是可以找到的,只是课后作业习题和考试页面已经无法使用了。所以当初那些没有完成的课程,我希望能继续,乘现在空闲时间还比较多的时候。于是从《图像与视屏处理》这门课程开始。

重新学习,自然需要吸取前面的教训。

  1. 重视课程。

    说实话前面学习时好奇心过于旺盛、心态上有点浮躁。课程简单的时候迫切的想看后面的章节,课程复杂的时候,又没有耐心的去思考。

  2. 注重理解。

    由于没有课后习题的练习,所以要加深所学知识的理解只能靠自己思考了。我现在想到的就是,学完一部分内容,整理后发布在Blog上。

    其实前面学习的时候也做过记录,但是当时仅仅是将视屏讲解的内容原原本本的抄下来没有经过自己的整理,这是远远不够的。现在的话,我希望按照自己的理解的思路来写,不求面面俱到(因为交涉的知识点太多面面俱到是不可能的),但是需要有轻重详略,且内容结构不完全和课程一样,以自己的思路为主,我会将我认为的重点以及我理解得很透彻的点解释的更详细些。

Compartir

前端基础学习小结

学习感悟

最近这段时间,走马观花的看了一些关于前端技术的教程,总算大致明白了前端技术的基本原理和开发流程。学习的原因很简单,第一是好奇,第二是在互联网多媒体不断发展的现在前端技术实在是用途太广泛了,一点都是知道的话,都不好意思说自己的是码代码的。

我想对于像我这样,刚开始一无所知的人来说,面对一门新的技术,最想知道的应该是:它的是做什么用的(它有什么作用),然后就是:它是怎么用的(怎么使用它),最后才是那些具体的知识点。忽略前面两点而直接开讲的,套用现在比较流行的话说,就是耍流氓。现在我来整理和总结前面七零八落的知识,我希望记录的不仅仅是一些干活,还能够有自己对这些东西系统的立体的认识和理解。

前端技术是什么

前端技术准确的定义我现在还没有搞懂,但是按我的理解通来讲,前端技术用来开发web应用的,使用它能够通过浏览器与用户进行各种交互操作,能够通过网络和后端服务器进行数据交互。

基本组成

很多人都知道,前端技术最基本的三个组成部分:

  • HTML
  • CSS
  • JavaScript

HTML确定网页的框架
哪些内容是标题,哪里是正文,哪些是表格,有多少段落等等,这些都是有HTML控制。

CSS为网页各部分制定样式
网页中每个部分的位置、颜色、字体样式等等这些由CSS来设置。

JavaScript控制网页中的各种行为操作
当网页响应各种事件,需要和用户进行各种交互时,需要样式需要动态改变时,则需要JavaScript来操作

当然随着前端技术的发展,又有许多新的技术的加入。

如何使用

前端技术就是用来开发web应用的,通俗点讲的就是做网页。那是如何用这些东西来做出一个web应用呢?一个最最简单的web工程文件结构如下图:

proj_file

  • index.html是的网站的主页

    http服务器会将根目录下的index.html作为整个网页入口页面。Html文件都是由许多Html标签组成,而Html标签有可能会带一些有属性和值。

    一个最简单的html文件的结果如下:

    html_frame

    “<!DOCTYPE html>” 声明文档为html文档,然后下面是html标签,html标签将包裹整个页面,是最外层的标签。html标签里面由head标签和body两部份组成。head标签中主要是一些页面的声明,如title标签申明页面标题。body标签中便是页面所有内容,一般来说一个页面内容如上图所示可以分三个层次,由上到下依次是header、content、footer。这其中header和footer都有专业的标签,表示页头和页脚;而中间content页面主体部分没有单独的标签,它是由一个div容器包裹来构建的。

    熟悉html常用的标签非常重要,但是也不需要全部死记,w3c有专门的教学网站能够提供各种类型的标签的查询:http://www.w3school.com.cn/

  • CSS文件夹就是存放CSS样式等文件的地方

    页面要使用外部的CSS文件是需要在html文件中申明其引用的CSS文件的位置的。如:
    html_CSS

    如上图,在html页面中引用了一个叫reset.css的CSS文件。通常由于浏览器显示的区别,在写自己的样式前,都先要将样式重置一下,重置的代码可以在网上搜到(实际上这里的我这里reset.css就是器重置样式的作用的)。

    css文件写法如下图所示:

    CSS_file

    总的来说就用各种方法来选择,找到你要设置的html中的元素,然后用在后面跟着大括号,在其中设置其各种属性。如果不熟悉或者忘记了选择方法和属性同样可以在w3school网站上查询。

    html和CSS联系的比较紧密,二者结合可以是实现各种页面样式。在页面布局中比较重要的是 盒子模型,它体现一个页面块对象在其外层对象中的相对位置;另外一个比较重要的是 页面定位的方法

  • js文件夹是存放JavaScript脚本的地方

    js代码相对比较独立,目前接触的也比较少,没有什么感触

  • res文件夹是保存其他资源的文件夹,如图片

目前,我能理解的水平也只能到这里了,后续学习再来更新。

Compartir