2018-10-13 14:50:47    277    0    0

Python 中的 Zip

zip的作用:可以在处理循环时用到,返回一个将多个可迭代对象组合成一个元组序列的迭代器。每个元组都包含所有可迭代对象中该位置的元素。

  1. my_zip = list(zip(['a', 'b', 'c'], [1, 2, 3]))
  2. print(my_zip) # [('a', 1), ('b', 2), ('c', 3)]

正如 range() 一样,我们需要将其转换为列表或使用循环进行遍历以查看其中的元素。

  1. letters = ['a', 'b', 'c']
  2. nums = [1, 2, 3]
  3. for letter, num in zip(letters, nums):
  4. print("{}: {}".format(letter, num))

输出如下:

  1. a: 1
  2. b: 2
  3. c: 3

除了可以将两个列表组合到一起之外,还可以使用星号拆封列表,返回的是单个元组

  1. some_list = [('a', 1), ('b', 2), ('c', 3)]
  2. letters, nums = zip(*some_list)
  3. print(letters) # ('a', 'b', 'c')
  4. print(nums) # (1, 2, 3)

Python 中的 Enumerate

enumerate 是一个会返回元组迭代器的内置函数,这些元组包含列表的索引和值。当你需要在循环中获取可迭代对象的每个元素及其索引时,将经常用到该函数。

示例代码:

  1. letters = ['a', 'b', 'c', 'd', 'e']
  2. for i, letter in enumerate(letters):
  3. print(i, letter)

输出如下:

  1. 0 a
  2. 1 b
  3. 2 c
  4. 3 d
  5. 4 e

下面两种方式效果一样:

  1. a =[12,43,56,78] #将list转为dict,主要是为了提高查找提速
  2. b ={idx:i for idx,i in zip(range(len(a)),a)}
  3. b
  4. {0: 12, 1: 43, 2: 56, 3: 78}
  5. c ={idx:i for idx,i in enumerate(a)}
  6. c
  7. {0: 12, 1: 43, 2: 56
2018-10-09 22:52:45    315    0    0

1.torch.cat()进行tensor的拼接

  1. import torch
  2. a = torch.ones([1,2])
  3. b = torch.ones([1,2])
  4. torch.cat([a,b],1)
  5. 1 1 1 1
  6. [torch.FloatTensor of size 1x4]

如果第二个参数是1,torch.cat就是将a,b 按列放在一起,大小为torch.Size([1,4])。如果第二个参数是0,则按行

行放在一起,大小为 torch.Size([2, 2]) 。

第二个参数默认是0
注意:拓展的理解,第二个参数dim代表拼接在一起的维度,其他维度必须保持一致:

  1. frac1=torch.ones(2,3,8,5)
  2. frac2=torch.zeros(2,3,2,5)
  3. torch.cat((frac1,frac1,frac2),dim=2) #其他维度不一致会出错,可以多个一起拼接
  1. torch.cat(seq,dim=0,out=None) # 沿着dim连接seq中的tensor, 所有的tensor必须有相同的size或为empty, 其相反的操作为 torch.split() 和torch.chunk()
  2. torch.stack(seq, dim=0, out=None) #同上
  1. #注: .cat 和 .stack的区别在于 cat会增加现有维度的值,可以理解为`续接`,stack会新加增加一个维度(多一个大括号,包起来),可以理解为`叠加`
  2. >>> a=torch.Tensor([1,2,3])
  3. >>> torch.stack((a,a)).size()
  4. torch.size(2,3)
  5. >>> torch.cat((a,a))
2018-10-08 20:47:30    699    0    0

一.介绍

在使用matplotlib的过程中,发现不能像matlab一样同时开几个窗口进行比较,于是查询得知了交互模式,但是放在脚本里运行的适合却总是一闪而过,图像并不停留,遂仔细阅读和理解了一下文档,记下解决办法,问题比较简单,仅供菜鸟参考。

python可视化库matplotlib有两种显示模式:

×阻塞(block)模式
×交互(interactive)模式

在Python Consol命令行中,默认是交互模式。而在python脚本中,matplotlib默认是阻塞模式
jupyter notebook中,默认是交互模式的(因此去掉plt.ion(),plt.ioff(),plt.show(),都不会影响原来的效果),而且貌似不能改为阻塞模式????,但是显示图像并不会开一个窗口,而是会一张一张的全部显示在网页上,所以即使是“一闪而过”,也看不出来。想要实时动态的显示,参看其他笔记“jupyter notebook matplotlib画图动态刷新”

二.阻塞与交互的区别

在交互模式下

plt.plot(x)或plt.imshow(x)是直接出图像,不需要plt.show() 貌似还是需要,否则一闪而过
如果在脚本中使用ion()命令开启了交互模式,没有使用ioff()关闭的话,则图像会一闪而过,并不会常留。要想防止这种情况,需要在plt.show()之前加上ioff()命令。这倒是对的

在阻塞模式下

打开一个窗口以后必须关掉才能打开下一个新的窗口。这种情况下,默认是不能像Matlab一样同时开很多窗口进行对比的。这也是对的
plt.plot(x)或plt.imshow(x)是不直接出图像,需要plt.show()后才能显示图像

三.一个简单的示例

下面这个例子讲的是如何像matlab一样同时打开多个窗口显示图片或线条进行比较,同时也是在脚本中开启交互模式后图像一闪而过的解决办法:

  1. import matplotlib.pyplot as plt
  2. plt.ion() # 打开交互模式,实际上交互模式在只打开一个figure窗口的情况下,与阻塞模式没啥区别
  3. # 同时打开两个窗
2018-10-08 11:58:06    954    0    0

jupyter notebook 是基于网页的,因此默认情况下不会动态画图,哪怕是加了plot.ion() 和 plt.ioff()也不行,可以在开头加入如下代码:

  1. import matplotlib
  2. %matplotlib inline
  3. from IPython import display

然后在需要刷新的地方,也就是画完一次图之后添加(可以放在print()后面)

  1. display.clear_output(wait=True)

这样就会在原来基础上继续画图,在网页上形成动态效果.

2018-10-07 23:04:19    274    0    0

一个非常好的matplotlib教程:
https://www.cnblogs.com/duye/p/8862666.html

1. matplotlib api 入门

matplotlib api函数都位于maptplotlib.pyplot模块中画图的各种方法:

Figure:画图窗口,有点类似于画图需要的画布
Subplot/add_Subplot: 创建一个或多个子图,并且返回子图对象
Subplots_adjust:调整subplot周围的间距
color/linestyle/marker: 线颜色,线型,标记
drawstyle:线型选项修改
xlim: 图表范围,有两个方法get_xlim和set_xlim
xticks:刻度位置,有两个方法get_xticks和set_xticksxtick
labels: 刻度标签,有两个方法get_xticklabels和set_xticklabels
legend: 添加图例。plt.legend(loc='best')

2.plot方法:

1、plt.plot(x,y,format_string,**kwargs)

x轴数据,y轴数据,format_string控制曲线的格式字串
format_string 由颜色字符,风格字符,和标记字符:

  1. fig=plt.figure(figsize=(8,6))
  2. ax1 =fig.add_subplot(221)
  3. ax1.plot(x.numpy(),y2.numpy(),'green','-',lw=1,label='square-randn')#在ax1上画图,'green'要在'-'前面,相当于'g-'
  4. #ax1.plot(x.numpy(),y2.numpy(),'g-',lw=1,label='square-randn')
  5. ax1.legend(loc='best')

title
title

关于*kwargs,有时候,函数的参数里会有(*args, *kargs),都是可变参数,*args表示无名参数,是一个元租,**kwargs是键值参数,相当于一个字典,比如你输入参数为

2018-10-05 15:07:35    85    0    0

1.对数变换和幂律变换中的C该如何取值,才能得到图3.3和3.6的曲线?

对数变换: c>1增强对比度,反之降低对比度
幂律变换: c>1增强对比度,反之降低对比度

2.比特面分层应该如何实现?

对于灰度图而言,一个像素点由8个比特组成。代替突出灰度级范围,我们可以突出特定比特来为整个图像外观作出贡献(理解这一点很重要)一副8比特灰度图可考虑分层1到8个比特平面。很容易理解的是,4个高阶比特平面,特别是最后两个比特平面,包含了在视觉上很重要的大多数数据。而低阶比特平面则在图像上贡献了更精细的灰度细节。

比特平面分层最重要的是它的分层算法,算法依据就是上段的黑体字,突出该层的比特,如何突出则是每一层分层算法需要考虑的。
例如第一层,值不是0就是1,这样的色值显示出来就是纯黑,根本显现不了第一层比特的贡献。突出分层的最好做法就是二值化,因为每个像素点每层比特的值只有1(有贡献)和0(无贡献),我们要做的就是突出1值,将1值扩大为255,然后显示即可。
其它层级的分层算法如上依次类推,如果该层级的比特值为1,则二值化为255,如果为0,则二值化为0。
参考资料
http://www.cnblogs.com/fordreamxin/p/4621119.html

3.什么是图像的直方图?如何用程序实现直方图统计?

一幅图像由不同灰度值的像素组成,图像中灰度的分布情况是该图像的一个重要特征。图像的灰度直方图就描述了图像中灰度分布情况,能够很直观的展示出图像中各个灰度级所占的多少。
图像的灰度直方图是灰度级的函数,描述的是图像中具有该灰度级的像素的个数:其中,横坐标是灰度级,纵坐标是该灰度级出现的频率。
如何计算:

  1. int grysm=0;//假设为像素总和
  2. int hist[255]={0};//统计结果的数组
  3. void calhist(Mat& input){
  4. Mat mat=input.clones();
  5. grysm=mat.cols*mat.rows;
  6. for(int i=0;i<mat.rows;i++)
  7. {
  8. for(int j=0;j<mat.cols;j++
2018-10-05 14:22:06    52    0    0

彩色摄像头(相机)原理?

很多数字相机采用电荷耦合器件(CCD)作为其感光元器件。CCD 的原理很简单:我们可以把它想象成一个没有盖子的芯片,上面整齐地排列着很多小的感光单元,光线中的光子撞击每个单元后,在这些单元中会产生电子(光电效应),而且光子的数目与电子的数目互成比例。但在这一过程中,光子的波长并没有被转换为任何形式的电信号,换言之,CCD 裸芯片实际上都没有把色彩信息转换为任何形式的电信号。那么采用 CCD 作为感光元件的彩色数字相机是如何生产彩*像的?本文将回答这个问题。

  1. 单色相机

我们首先从相对简单的黑白数字相机入手。

物体在有光线照射到它时将会产生反射,这些反射光线进入镜头光圈照射在CCD芯片上,在各个单元中生成电子。

曝光结束后,这些电子被从 CCD 芯片中读出,并由相机内部的微处理器进行初步处理。此时由该微处理器输出的就是一幅数字图像了。

  1. 3 CCD 彩色相机

CCD 芯片按比例将一定数量的光子转换为一定数量的电子,但光子的波长,也就是光线的颜色,却没有在这一过程中被转换为任何形式的电信号,因此 CCD 实际上是无法区分颜色的。

title

在这种情况下,如果我们希望使用 CCD 作为相机感光芯片,并输出红、绿、蓝三色分量,就可以采用一个分光棱镜和三个 CCD,如图所示。棱镜将光线中的红、绿、蓝三个基本色分开,使其分别投射在一个 CCD 上。这样以来,每个 CCD 就只对一种基本色分量感光。

这种解决方案在实际应用中的效果非常好,但它的最大缺点就在于,采用3个 CCD + 棱镜的搭配必然导致价格昂贵。因此科研人员在很多年前就开始研发只使用一个 CCD 芯片也能输出各种彩色分量的相机。

单片CCD如何产生彩色图像?

  1. 单 CCD 彩色相机

(1) 成像原理

如果在 CCD 表面覆盖一个只含红绿蓝三色的马赛克滤镜,再加上对其输出信号的处理算法,就可以实现一个 CCD 输出彩*像数字信号。由于这个设计理念最初由拜尔(Bayer)先生提出,所以这种滤镜也被称作拜尔滤镜。
title
如上图所示,该滤镜的色彩搭配形式为:一行使用蓝绿元素,下一行使用红绿元素,如此交替;换言之,CCD 中每4个像素中有2个对绿色分量

2018-10-02 22:55:52    680    0    0

1.首先在ubuntu下,直接去anaconda官网下载anaconda的linux版本,然后,在下载的文件目录下执行(根据版本做相应的改动)安装anaconda:

  1. bash Anaconda3-4.2.0-Linux-x86_64.sh

参考:
https://blog.csdn.net/u012318074/article/details/77074665

2.更新conda(如果有的话可以更新,并不一定要更新哈):

  1. $ conda update -n base conda

3.创建一个叫做pytorch的环境,指令为(=后面为版本号):

  1. conda create -n pytorch python=3.6.5

4.激活/关闭该环境(windows下打开conda命令行窗口,使用conda activate pytorch命令可以激活创建的pytorch环境,ubuntu下则不能直接使用conda指令,进入pytorch后则可以使用conda指令):

  1. source activate pytorch
  2. source deactivate

5.进入环境后,下载相应的包:
可参考pytorch官网给出的conda指令,或者另一篇笔记

  1. conda install pytorch torchvision cuda92 -c pytorch

6.安装完后,看是否能够import torch(默认是能够import torchvision的,因为现在官方包直接包括了torchvision):
在终端中,激活pytorch环境后,输入python,切换到python交互模式,这时import torch应该是没有什么问题的
在终端中,激活pytorch环境后,输入jupyter notebook后,进入jupyter笔记本后,import torch应该是会出错的,这是因为这时的jupyter notebook是在anaconda中的env环境之外安装的,比如现在可以去anancodna3/bin/下面可以看到相关的jupyter文件,这个jupyter notebook与env中的pytorch是无关的,而即使是

2018-09-27 10:49:51    53    0    0

只要是学过C/C++语言的人,肯定会被指针“坑过”,或者是使用了空指针,或者是将指针指向了非法区域并试图访问它。Java宣称,你们解放了,大家都不用学指针啦!于是,小白们欢呼雀跃。殊不知,Java确实没有指针概念,因为它的每个变量都是指针。“NullPointerException”已经太经典,所以无需举例。 还有的人为了躲开讨厌的C语言指针和臃肿的Java代码,学了更易上手的Python。他们可能不知道,Python依然无法避免引入指针概念。下面是一个小例子:

  1. In [1]: result = [[0, 0]]* 3
  2. In [2]: result
  3. Out[2]: [[0, 0], [0, 0], [0, 0]]

目前看来,代码的输出如你所想。然后,我们尝试为result中的元素赋值:

  1. In [3]: result[0][0] = 3
  2. In [4]: result
  3. Out[4]: [[3, 0], [3, 0], [3, 0]]

嗯?输出结果是否跟你想象中的不一样呢?本想只对result中的第0个元素操作,但是result中的所有三个元素都有了变化。再尝试一下:

  1. In [5]: result[0][1] = 5
  2. In [6]: result
  3. Out[6]: [[3, 5], [3, 5], [3, 5]]

似乎result中的三个元素的值是同步变化的。其实,不难猜想,result这个list中包含的三个list(初始为[0,0])其实指向的是一个list实例,而result[0], result[1]以及result[2]都是指向这个实例的指针,所以result中的三个元素是同步变化的。这个猜想可以通过调用id()来查看object的内存地址来验证:

  1. In [10]: id(result[0])
  2. Out[10]: 159288460
  3. In [11]: id(result[1])
  4. Out[11]: 159288460
  5. In [12]: id(result[2])
  6. Out[12]: 159288460

那么如何达到预想的效果呢?即改变result[0]的值,而result[1], result[2]不受影响。可以这样初始化result(笨方法

2018-09-26 18:23:40    164    0    0

简书上写得很好的一篇numpy教程:
https://www.jianshu.com/p/60bf50100c2f

一.基础篇

NumPy的主要对象是同种元素的多维数组。这是一个所有的元素都是一种类型、通过一个正整数元组索引的元素表格(通常是元素是数字)。在NumPy中维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank)。

例如,在3D空间一个点的坐标 [1, 2, 3] 是一个秩为1的数组,因为它只有一个轴。那个轴长度为3.又例如,在以下例子中,数组的秩为2(它有两个维度).第一个维度长度为2,第二个维度长度为3.

  1. a=[[ 1., 0., 0.], [ 0., 1., 2.]]#alist类型的,且其元素是浮点类型的,不会有reshape方法
  2. import numpy as np
  3. a=np.arange(15).reshape(3,5)#aanumpy.ndarray类型的,可以通过type()方法查看
  4. from numpy import * #这样子可以不给模块取名
  5. a=arange(24).reshape(2,3,4)

Python已有列表类型,为什么需要一个数组对象(类型)?
例:计算 A 2 +B 3 ,其中,A和B是一维数组。

方法1:

  1. def pysum():
  2. a = [0, 1, 2, 3, 4,]
  3. b = [9, 8, 7, 6, 5,]
  4. c = [] for i in range(len(a)):
  5. c.append(a[i]**2 + b[i]**2)
  6. return c
  7. print(pysum())

方法2:

  1. import numpy as np
  2. def npsum():
  3. a = np.array([0, 1, 2, 3, 4,])
  4. b = np.array([9, 8, 7, 6, 5,])
  5. c = a**2 + b**2
  6. return c
  7. print(npsum())

对比方法1和方法2,我们可以得到:

• 数组对象可以去掉元素