kornia/kornia-rs

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

Open

#659 opened on Jan 22, 2026

View on GitHub
 (4 comments) (0 reactions) (1 assignee)Rust (188 forks)auto 404
bughelp wanted

Repository metrics

Stars
 (675 stars)
PR merge metrics
 (PR metrics pending)

Description

🐛 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

Contributor guide