import os

from torchvision import transforms
import torch
import numpy as np
import cv2
import os
from utils import *

import pandas as pd

# Smaller radius (R=1) captures fine details
# Larger radius captures more coarse patterns
# Consider using uniform patterns for dimensionality reduction
def get_lbp_features(image, P=8, R=2):
    """
    Compute Local Binary Pattern features for an image
    
    Args:
        image: torch.Tensor of shape (B, 1, H, W) - grayscale image batch
        P: Number of sampling points (default: 8)
        R: Radius of the circle (default: 1)
    
    Returns:
        LBP features tensor of shape (B, 1, H-2, W-2)
    """
    device = image.device
    batch_size, _, height, width = image.shape
    
    # Generate sampling coordinates
    angles = 2 * np.pi * np.arange(P) / P
    sample_x = R * np.cos(angles)
    sample_y = R * np.sin(angles)
    
    # Round to nearest pixel
    sample_x = np.round(sample_x).astype(int)
    sample_y = np.round(sample_y).astype(int)
    
    # Initialize output tensor
    lbp = torch.zeros((batch_size, 1, height-2*R, width-2*R), device=device)
    
    # Compute LBP
    center = image[:, :, R:height-R, R:width-R]
    
    for i in range(P):
        # Get neighbor pixel values
        neighbor = image[:, :, 
                       R+sample_y[i]:height-R+sample_y[i],
                       R+sample_x[i]:width-R+sample_x[i]]
        # Compare with center
        lbp += (neighbor > center).float() * (2**i)
    
    return lbp
