filter using ffmpeg on linux with rembg
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# Photo Background Remover
|
||||
|
||||
A simple Go program that captures a photo from your webcam and removes the background.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### 1. Install ffmpeg
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt install ffmpeg
|
||||
|
||||
# macOS
|
||||
brew install ffmpeg
|
||||
```
|
||||
|
||||
### 2. Install Docker
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt install docker.io
|
||||
|
||||
# macOS
|
||||
brew install --cask docker
|
||||
```
|
||||
|
||||
The program uses the `danielgatis/rembg` Docker container for background removal. The AI model (~176MB) will be downloaded automatically on first run.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Build and run the program:
|
||||
```bash
|
||||
go run main.go
|
||||
```
|
||||
|
||||
2. The program will:
|
||||
- Capture a photo from your webcam
|
||||
- Remove the background
|
||||
- Save both images in the `output/` directory
|
||||
|
||||
## Output
|
||||
|
||||
- `output/photo_TIMESTAMP.jpg` - Original photo
|
||||
- `output/photo_TIMESTAMP_nobg.png` - Photo with background removed
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Webcam not found**: Make sure `/dev/video0` exists (Linux) or adjust the device in the code
|
||||
- **ffmpeg not found**: Install ffmpeg using the commands above
|
||||
- **Docker not found**: Install Docker using the commands above
|
||||
- **Docker permission denied**: Add your user to the docker group: `sudo usermod -a -G docker $USER` (then log out and back in)
|
||||
- **Webcam permission denied**: You may need to add your user to the `video` group: `sudo usermod -a -G video $USER`
|
||||
@@ -0,0 +1,105 @@
|
||||
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
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 220 KiB |
Reference in New Issue
Block a user