DigitalMicrograph中1D核化边缘检测的Warp适配及替代方案问询
关于DigitalMicrograph脚本1D边缘检测核方法的解决方案
现有实现代码
一阶导数
Image absolute_first_derivative(Image in) { Number size_x, size_y, origin, scale; String units; Image out; in.ImageGetDimensionCalibration(0, origin, scale, units, 0); in.GetSize(size_x, size_y); if (size_y != 1) Result("Only compatible with 1D image"); out := RealImage("first_derivative", 4, size_x, size_y); out = in[icol + 1, irow] - in[icol, irow]; out[0, 0] = 0; out[size_x - 1, 0] = 0; out.ImageSetDimensionCalibration(0, origin, scale, units, 0); return out; }
二阶导数
Image second_derivative(Image in) { Number size_x, size_y, origin, scale; String units; Image out; in.ImageGetDimensionCalibration(0, origin, scale, units, 0); in.GetSize(size_x, size_y); if (size_y != 1) Result("Only compatible with 1D image"); out := RealImage("second_derivative", 4, size_x, size_y); out = in[icol + 1, irow] - 2 * in[icol, irow] + in[icol - 1, irow]; out[0, 0] = 0; out[size_x - 1, 0] = 0; out.ImageSetDimensionCalibration(0, origin, scale, units, 0); return out; }
问题解答
1. Warp()函数能否适配1D图像处理?
Warp()函数本质为2D几何变换设计,虽然可以将1D图像转为单通道2D格式(保持size_y=1)强行调用,但这种方式既不高效也不符合函数设计初衷。Warp()并不适合核卷积类操作,因此不建议用它实现1D边缘检测的核方法。
2. 适合1D图像的核卷积方法
DigitalMicrograph提供了专门的卷积内置函数,更适合实现基于核的1D边缘检测,推荐以下两种方案:
方案一:使用Convolve()函数做空间域卷积
Convolve()支持1D和2D图像卷积,只需创建对应的1D核即可,示例如下:
1D Sobel核一阶导数实现
Image sobel_1d_first_derivative(Image in) { Number size_x, size_y, origin, scale; String units; in.GetSize(size_x, size_y); if (size_y != 1) { Result("Only compatible with 1D image\n"); return NULL; } // 创建1D Sobel核([-1, 0, 1],用于一阶边缘检测) Image kernel := RealImage("Sobel 1D Kernel", 4, 3, 1); kernel[0,0] = -1; kernel[1,0] = 0; kernel[2,0] = 1; // 执行卷积,设置边界处理模式(0=零填充) Image out := Convolve(in, kernel, 0); // 复制校准信息 in.ImageGetDimensionCalibration(0, origin, scale, units, 0); out.ImageSetDimensionCalibration(0, origin, scale, units, 0); out.SetName("1D Sobel First Derivative"); return out; }
1D LoG核二阶导数实现
Image log_1d_second_derivative(Image in) { Number size_x, size_y, origin, scale; String units; in.GetSize(size_x, size_y); if (size_y != 1) { Result("Only compatible with 1D image\n"); return NULL; } // 创建1D LoG核([-1, 2, -1],简化版二阶边缘检测核) Image kernel := RealImage("LoG 1D Kernel", 4, 3, 1); kernel[0,0] = -1; kernel[1,0] = 2; kernel[2,0] = -1; // 执行卷积,边界用0填充 Image out := Convolve(in, kernel, 0); // 复制校准信息 in.ImageGetDimensionCalibration(0, origin, scale, units, 0); out.ImageSetDimensionCalibration(0, origin, scale, units, 0); out.SetName("1D LoG Second Derivative"); return out; }
方案二:使用FFTConvolve()做频域卷积
如果使用较大的1D核,频域卷积效率更高,FFTConvolve()同样支持1D图像:
Image fft_convolve_1d(Image in, Image kernel) { Number size_x, size_y; in.GetSize(size_x, size_y); if (size_y != 1 || kernel.ImageGetDimensionSize(1) != 1) { Result("Input and kernel must be 1D images\n"); return NULL; } // 频域卷积,自动处理尺寸匹配 Image out := FFTConvolve(in, kernel); // 复制校准信息 Number origin, scale; String units; in.ImageGetDimensionCalibration(0, origin, scale, units, 0); out.ImageSetDimensionCalibration(0, origin, scale, units, 0); return out; }
额外建议
- 处理边界时,
Convolve()的第三个参数可设置不同模式:0=零填充,1=边缘复制,2=镜像翻转,可根据需求选择。 - 自定义核时,建议使用奇数尺寸,方便对齐中心像素。
内容的提问来源于stack exchange,提问作者Samuel Hao
相关产品推荐
相关产品推荐

