文章目录
- 图像裁切
- 给定坐标裁切
- 手动阈值裁切
光斑处理:python处理高斯光束的图像
光斑处理系统:程序框架🌟打开图像🌟参数对话框/伪彩映射
图像裁切
一般来说,光斑只占图像很小一部分,为了更好的观感和更小的误差,将背底区域截掉是一个必要的选择,为此需要实现图像裁切功能,即选中感兴趣的区域(ROI)
而选中ROI,其实有多种方案,比如
- ‘roi’ 直接给定起始 x x x和 y y y坐标
- ‘thres’ 手动阈值裁切
- ‘auto’ 自动阈值裁切
- ‘click’ 点击举行的对角点,手动选择区域
下面逐一实现。
给定坐标裁切
首先,为裁切功能设置一个参数对话框,其内容包括裁切模式,当处于手动阈值裁切时,需要设置阈值,最后,当给定坐标时,需要设置坐标的起始位置,累计下列6个参数。
class AnaFacula():
# 前面省略,后面凡是带有self参数的函数,均写在AnaFacula中
def init_param(self):
# 前面省略
# 剪切参数
self.cutPara = {
"mode":"click",
"thres":10.0,
"xStart":0,
"xEnd":0,
"yStart":0,
"yEnd":0,
}
然后修改img_cut函数,从裁切的流程出发,无论采取何种模式,最终势必需要通过起止位置来完成裁切,所以先建立一个通用的裁切函数。
def imgCut(self):
self.img = self.img[
self.cutPara['yStart']:self.cutPara['yEnd'],
self.cutPara['xStart']:self.cutPara['xEnd']]
self.imgShow()
而对于前面提到的四种方案而言,只有第一种,即roi模式下,才会直接执行imgCut,所以img_cut可暂时写为下面的形式,换言之,其他三种模式都需要对cutValue进行更新。
def img_cut(self):
flag, cutPara = inputValue(self.cutPara)
if not flag:
return
for key in cutPara:
if key != None:
self.cutPara[key] = cutPara[key]
if cutPara['mode'] == 'auto':
pass
elif cutPara['mode'] == 'thres':
pass
elif cutPara['mode'] == 'click':
pass
self.imgCut()
修改完成后,在裁切之后,再次打开裁切按钮,其参数会更新为上次设置的参数,切割效果如下
手动阈值裁切
所谓手动阈值裁切,就是通过一个阈值对图像二值化,然后统计大于这个阈值的像素个数,假设这些像素围成一个圆形,那么由此可得到这个圆形的半径。再通过求取图像的质心,即可得到一个正方形的区域,可作为裁切的标记。
def getROI(img,thres=None):
m, n = img.shape
img = img + 0 # 深拷贝
img[img<thres] = 0 # 背底置零
radius = np.sqrt(np.sum(img>0)/np.pi)
allSum = np.sum(img)
if allSum == 0:
return None
yC = np.sum(np.sum(img,1)*np.arange(m))/allSum
xC = np.sum(np.sum(img,0)*np.arange(n))/allSum
xStart = max(0,int(xC-radius))
xEnd = min(m,int(xC+radius))
yStart = max(0,int(yC-radius))
yEnd = min(n,int(yC+radius))
print(radius, xStart)
return {'xStart':xStart, 'xEnd':xEnd, 'yStart':yStart, 'yEnd':yEnd}
相应地,修改thres模式下的代码。
elif cutPara['mode'] == 'thres':
roi = getROI(self.img, self.cutPara['thres'])
for key in roi:
self.cutPara[key] = roi[key]
手动阈值裁切效果如下
自动阈值只比手动阈值多了一个求阈值的操作,可采取OTSU算法,由于算法严格来说并不算是业务流程的内容,所以放在后面有空再将;通过点击的方式实现区域选取,则需要新建一个鼠标响应函数,相对来说较为复杂,故而也放在后面讲解。