如何去除图片左边缘亮线并提升图像动态范围?
图像左边缘白线去除及动态范围优化
从bin文件生成图像后,左边缘出现贯穿高度的1像素白线,该白线拉低了图像整体动态范围,导致小数值区域难以分辨。生成图像的Python代码如下:
import matplotlib.pyplot as plt import numpy as np import time from PIL import Image import math import numpy as np import json import pickle import matplotlib.cm as cm import PIL.ImageOps #from libtiff import TIFFfile, TIFFimage import tifffile def micronToStep(v): #approximately 62nm/step return round((v * 1000)/62) def normalizeData(data): return (data - np.min(data)) / (np.max(data) - np.min(data)) def moving_average(x, w): return np.convolve(x, np.ones(w), 'valid') / w def annot_max(x,y, ax=None): xmax = x[np.argmax(y)] ymax = y.max() text= "x={:.3f}, y={:.3f}".format(xmax, ymax) if not ax: ax=plt.gca() bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72) arrowprops=dict(arrowstyle="->",connectionstyle="angle,angleA=0,angleB=60") kw = dict(xycoords='data',textcoords="axes fraction", arrowprops=arrowprops, bbox=bbox_props, ha="right", va="top") ax.annotate(text, xy=(xmax, ymax), xytext=(0.94,0.96), **kw) fo = open('saveData2.bin', 'rb') data = pickle.load(fo) fo.close() print("xyStep: ", data['xyStep']) print("xRange: ", data['xRange']) print("yRange: ", data['yRange']) print("zRange: ", data['zRange']) print("zBase: ", data['zBase']) dimX = math.ceil(data['xRange'] / data['xyStep']) dimY = math.ceil(data['yRange'] / data['xyStep']) print(dimX, dimY) img = np.zeros((dimX, dimY)).astype('uint16') zRange = data['zRange'] imgData = data['data'] minValue = 999999999 maxValue = -999999999 for i in range(0, dimX): for j in range(0, dimY): if type(imgData[i][j]) is np.ndarray: try: smoothed = moving_average(imgData[i][j], 10) height = smoothed.argmax() # / smoothed.shape[0]) * zRange except TypeError: height = 0 #if imgData[i][j] is None: # height = 0 # print("none", i,j) #else: # height = imgData[i][j].argmax() img[i][j] = height minValue = min(minValue, height) maxValue = max(maxValue, height) print("Min: ", minValue) print("Max: ", maxValue) tifffile.imwrite('saveData2.tif', img)
生成的图像左侧可见贯穿高度的1像素白线,以下是具体解决方法:
一、直接裁剪异常列(快速解决)
白线对应数组的第一列(索引i=0),若确认该列属于无效采集数据,可直接裁剪掉这一列,同时重新计算有效区域的极值以恢复动态范围:
# 在计算完原minValue和maxValue之后,添加裁剪逻辑 img = img[1:, :] # 移除第一列(所有行的i=0索引) # 重新计算有效区域的min和max minValue = np.min(img) maxValue = np.max(img) print("修正后 Min: ", minValue) print("修正后 Max: ", maxValue) # 写入tif文件 tifffile.imwrite('saveData2.tif', img)
二、排查并修复数据异常根源
如果第一列应为有效数据,可通过日志排查异常原因:
- 在循环中添加第一列的数据日志:
for i in range(0, dimX): for j in range(0, dimY): if i == 0: # 打印第一列的每个数据项类型和内容 print(f"i=0, j={j}, 数据类型={type(imgData[i][j])}, 数据内容={imgData[i][j]}") # 原循环逻辑...
- 根据日志结果针对性修复:
- 若第一列数据触发了
TypeError导致height=0,可调整moving_average的处理逻辑,比如缩小平滑窗口或跳过空数据; - 若
imgData[0][j]本身为无效值,可从源数据中排查采集环节的问题。
- 若第一列数据触发了
三、优化动态范围可视化(可选)
如果后续需要对图像进行可视化,可使用normalizeData函数对裁剪后的图像数据做归一化,进一步提升小数值区域的辨识度:
normalized_img = normalizeData(img) # 示例:使用matplotlib显示归一化后的图像 plt.imshow(normalized_img, cmap='viridis') plt.colorbar() plt.show()
内容的提问来源于stack exchange,提问作者Malum Phobos
相关产品推荐
相关产品推荐

