kornia/kornia-rs

[Bug]: sobel_kernel_1d panics for kernel sizes other than 3 or 5

Open

#659 建立於 2026年1月22日

在 GitHub 查看
 (4 留言) (0 反應) (1 負責人)Rust (188 fork)auto 404
bughelp wanted

倉庫指標

Star
 (675 star)
PR 合併指標
 (PR 指標待抓取)

描述

🐛 Describe the bug

The sobel_kernel_1d function in crates/kornia-imgproc/src/filter/kernels.rs panics when given a kernel size other than 3 or 5, instead of returning a Result with an error or expanding to larger kernel size. This can crash applications unexpectedly.

🔄 Steps to Reproduce

1. Create an image for edge detection
2. Call [sobel()] function with kernel size other than 3 or 5
3. Program crashes with panic message

💻 Minimal Code Example

use kornia_image::{Image, ImageSize, allocator::CpuAllocator};
use kornia_imgproc::filter::sobel;
fn main() {
    // Create a test image
    let img = Image::<f32, 1, _>::new(
        ImageSize { width: 100, height: 100 },
        vec![0.5; 10000],
        CpuAllocator
    ).unwrap();
    
    let mut dst = Image::from_size_val(img.size(), 0.0, CpuAllocator).unwrap();
    
    // This crashes the program
    sobel(&img, &mut dst, 7).unwrap();  // Panic!
}

✅ Expected behavior

The function should return a Result type allowing graceful error handling:

match sobel(&img, &mut dst, 7) {
    Ok(_) => println!("Edge detection successful"),
    Err(e) => eprintln!("Error: {}", e),  // Handle error
}

or we can fallback to 5×5 for any invalid size with a warning:

pub fn sobel_kernel_1d(kernel_size: usize) -> (Vec<f32>, Vec<f32>) {
    let (kernel_x, kernel_y) = match kernel_size {
        3 => (vec![-1.0, 0.0, 1.0], vec![1.0, 2.0, 1.0]),
        5 => (vec![1.0, 4.0, 6.0, 4.0, 1.0], vec![-1.0, -2.0, 0.0, 2.0, 1.0]),
        _ => {
            eprintln!("Warning: Invalid Sobel kernel size {}. Falling back to 5×5.", kernel_size);
            (vec![1.0, 4.0, 6.0, 4.0, 1.0], vec![-1.0, -2.0, 0.0, 2.0, 1.0])
        }
    };
    (kernel_x, kernel_y)
}

or apply Gaussian Derivative for arbitrary sizes Support arbitrary odd kernel sizes by computing Gaussian derivatives dynamically:

pub fn sobel_kernel_1d(kernel_size: usize) -> Result<(Vec<f32>, Vec<f32>), String> {
    let (kernel_x, kernel_y) = match kernel_size {
        3 => (vec![-1.0, 0.0, 1.0], vec![1.0, 2.0, 1.0]),
        5 => (vec![1.0, 4.0, 6.0, 4.0, 1.0], vec![-1.0, -2.0, 0.0, 2.0, 1.0]),
        
        // For other odd sizes, use Gaussian derivative
        _ if kernel_size % 2 == 1 && kernel_size >= 3 => {
            let sigma = (kernel_size as f32 - 1.0) / 6.0;
            let smooth = gaussian_kernel_1d(kernel_size, sigma);
            let deriv = gaussian_derivative_1d(kernel_size, sigma);
            (deriv, smooth)
        }
        
        _ => return Err(format!("Kernel size must be odd and >= 3, got {}", kernel_size)),
    };
    Ok((kernel_x, kernel_y))
}
// Helper function
fn gaussian_derivative_1d(size: usize, sigma: f32) -> Vec<f32> {
    // Compute derivative of Gaussian: -x/σ² * exp(-x²/2σ²)
    // implementation details
}

❌ Actual behavior

Calling sobel with kernel_size = 7...
thread 'main' (6036) panicked at
crates\kornia-imgproc\src\filter\kernels.rs:59:14:
Invalid kernel size for sobel kernel
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\test_sobel_panic.exe` (exit code: 101)

🔧 Environment

  • kornia-rs version: 0.1.11-rc.1
  • Rust version: 1.92.0
  • Cargo version: 1.92.0
  • OS: Windows, can test in Linux(Debian)
  • Target architecture: x86_64
  • Python version (if using Python bindings):N/A

📝 Additional context

I would like to work on the issue.

🤝 Contribution Intent

  • I plan to submit a PR to fix this bug
  • I'm reporting this bug but not planning to fix it

貢獻者指南