0%

电子衍射点标定的python语言描述

由于博主在实验过程中需要大量使用透射电镜,尤其是明场(Bright-field)和电子衍射(Electron diffraction)。为了大大减轻标定电子衍射点的工程,博主决定编写一个自动标定电子衍射的工具。

在具体介绍代码之前有必要先讲一下手动标定电子衍射的过程,如果不了解电子衍射标定原理的也不要紧,后面我会专门介绍电子衍射的原理。电子衍射是用来判断高分子结晶晶型的重要工具,正常拍完电子衍射后,CCD相机配套的软件都会根据已有的数据把标尺加到图上。如下图是取向聚1-丁烯薄膜的电子衍射图,图中左下角2 1/nm是标尺,不过这个是倒易空间的标尺,与传统的实空间的标尺并不一样,它的单位是1/nm,图中2 1/nm表示标尺的像素距离长度对应实空间的1/2 nm。原理以后再行解释,这里简单说一下,方便大家理解如何通过标尺计算晶面距离。

DigitalMicrograph(简称DM软件)可以用来完成标定过程。当我们将dm3格式的数据导入软件中时,先确定衍射中心,之后在用鼠标点击衍射点的同时就会给出每个点对应晶面的实空间的距离。每个晶型有对应的晶胞参数,根据晶胞参数可以获悉各晶面对应的理论晶面间距,将实际标定出来的晶面间距与理论晶面间距对比,若是误差在0.05 Å以内,即可判定为同一晶面。有了DM软件似乎标定过程非常简单,但是有一个问题,如果你没有源格式文件,只有一张普通的 jpg/png/tif 图片,那么上述过程只是一句空话。因此这篇博文就是为了实现普通图片格式的电子衍射图片进行标定而写的。你也可以把下面的代码理解为一个API,而它的作用就是让你如同使用软件那样方便的实现上述标定过程。具体代码如下:

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
import cv2
import numpy as np
import math

# 确定衍射中心,正常是先运行一部分代码把衍射中心标出来,输入下面的语句里
centre_weight = 1947
centre_height = 1393

# scale_1_nm_1 = 186.70691058147796
# 这个参数代表了电子衍射图中晶面间距为1 nm时像素点距离(即多少个像素点代表1 nm),这个从图中的标尺就可以确定的
scale_1_nm_1 = 188.2


## scale_1_nm_1 = 184.90267399364456
# scale_1_nm_1 = 1501.8995768163063

def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):
"""在图片中绘制坐标和晶面距离,括号里前两个数字分别代表衍射点在图中的像素坐标,第三个数字代表了根据标尺标定出来的晶面距离"""
if event == cv2.EVENT_LBUTTONDOWN:
d = crystal_distance(x, y)
xy = "%d, %d, %.4f" % (x, y, d)
cv2.circle(fic, (x, y), 1, (255, 0, 0), thickness = -1)
cv2.putText(fic, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,
2.0, (255, 255, 255), thickness = 2)
cv2.imshow("result", fic)


def crystal_distance(x, y):
"""计算像素距离,并将之转化为实际晶面距离"""
d = math.sqrt((x-centre_weight)**2 + (y-centre_height)**2)
d = scale_1_nm_1 / d
return d


while(True):
fic = cv2.imread('pvdf-pllagonghun04.tif')
cv2.namedWindow('result', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.setMouseCallback("result", on_EVENT_LBUTTONDOWN)
cv2.imshow("result", fic)
if cv2.waitKey(0) & 0xFF==27:
break
cv2.destroyAllWindows()

需要注意的是,代码需要运行两遍。第一遍是为了确定衍射点的像素坐标,将其替换代码中的数值后就可以开始标定电子衍射了。

当然如果有什么问题也可以留言给博主,我看到之后会回复的。这篇写的稍简单,如果没有基础的话可能会比较吃力,有基础的话应该没什么问题。另外需要解释一下的是因为博主主要做的是科研,业余码农,因此写的并不是那么的pythonic,若有不妥之处,诸位大家体谅。若是对诸君有些许帮助,本人不甚荣幸。

-------------本文结束感谢您的阅读-------------
您的支持将鼓励我继续创作!