package main import ( "fmt" "os" "os/exec" "path/filepath" "time" ) func main() { // Create output directory if it doesn't exist outputDir := "output" if err := os.MkdirAll(outputDir, 0755); err != nil { fmt.Printf("Error creating output directory: %v\n", err) os.Exit(1) } // Generate filenames with timestamp timestamp := time.Now().Format("20060102_150405") originalPhoto := filepath.Join(outputDir, fmt.Sprintf("photo_%s.jpg", timestamp)) processedPhoto := filepath.Join(outputDir, fmt.Sprintf("photo_%s_nobg.png", timestamp)) fmt.Println("šŸ“ø Capturing photo from webcam...") if err := capturePhoto(originalPhoto); err != nil { fmt.Printf("Error capturing photo: %v\n", err) os.Exit(1) } fmt.Printf("āœ“ Photo saved to: %s\n", originalPhoto) fmt.Println("šŸŽØ Removing background...") if err := removeBackground(originalPhoto, processedPhoto); err != nil { fmt.Printf("Error removing background: %v\n", err) os.Exit(1) } fmt.Printf("āœ“ Processed photo saved to: %s\n", processedPhoto) fmt.Println("\nšŸŽ‰ Done! Background removed successfully!") } // capturePhoto captures a single frame from the webcam using ffmpeg func capturePhoto(outputPath string) error { // For Linux, typically /dev/video0 // For macOS, use "0:0" with avfoundation // For Windows, use "video=CAMERA_NAME" with dshow var cmd *exec.Cmd // Detect platform and use appropriate video device if _, err := os.Stat("/dev/video0"); err == nil { // Linux cmd = exec.Command("ffmpeg", "-f", "v4l2", "-i", "/dev/video0", "-frames:v", "1", "-y", outputPath, ) } else { // Try macOS cmd = exec.Command("ffmpeg", "-f", "avfoundation", "-i", "0", "-frames:v", "1", "-y", outputPath, ) } output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("ffmpeg error: %v\nOutput: %s", err, string(output)) } return nil } // removeBackground removes the background using rembg Docker container func removeBackground(inputPath, outputPath string) error { // Get absolute path of current directory cwd, err := os.Getwd() if err != nil { return fmt.Errorf("failed to get working directory: %v", err) } // Docker paths are relative to /data mount point dockerInput := "/data/" + inputPath dockerOutput := "/data/" + outputPath // Use rembg Docker container cmd := exec.Command("docker", "run", "--rm", "-v", fmt.Sprintf("%s:/data", cwd), "danielgatis/rembg", "i", dockerInput, dockerOutput, ) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("docker/rembg error: %v\nOutput: %s", err, string(output)) } return nil }