如何在Processing中获取摄像头画面指定区域的平均颜色?
Hey there! No worries about messy code—we’ve all fumbled through our first Processing projects, so let’s break down why you’re only getting black for that rectangle’s average color.
Common Culprits & Fixes
1. You’re Not Updating the Camera’s Pixel Array
This is the most frequent issue for beginners! Processing doesn’t automatically sync the camera feed’s pixels to the pixels[] array—you have to tell it to load them every time a new frame arrives.
- Fix: Right after reading a new camera frame with
cam.read(), callcam.loadPixels(). This ensures you’re working with the latest pixel data, not an empty (black-by-default) array.
2. Your Pixel Index Calculation Is Wrong
Processing stores pixels in a 1D array where each row is stacked end-to-end. If you’re using the wrong formula to get the pixel at (x,y), you’ll end up grabbing pixels outside the valid area (which default to black).
- Correct Index: For a camera feed with width
cam.width, the index of pixel (x,y) isy * cam.width + x.
3. No Boundary Checks for the Rectangle
If your rectangle extends outside the camera’s resolution (e.g., negative coordinates, or width/height that go beyond cam.width/cam.height), you’ll be sampling invalid pixels that return black.
- Fix: Add a quick check inside your loop to make sure you only sample pixels within the camera’s bounds.
Example Working Code
Here’s a cleaned-up version that addresses all these issues, with comments to explain each step:
Capture cam; // Rectangle properties int rectX = 10; int rectY = 10; int rectW = 50; int rectH = 50; color avgRectColor; void setup() { size(640, 480); // Initialize camera with matching window resolution (adjust if needed) cam = new Capture(this, width, height); cam.start(); } void draw() { if (cam.available()) { // Step 1: Read new frame and load its pixels cam.read(); cam.loadPixels(); // Step 2: Calculate average color of the rectangle area avgRectColor = getAverageColor(rectX, rectY, rectW, rectH); // Step 3: Draw camera feed and rectangle image(cam, 0, 0); fill(avgRectColor); // Use the average color to fill the rectangle (optional) stroke(255); rect(rectX, rectY, rectW, rectH); // Optional: Display RGB values for debugging fill(255); text("Avg Color RGB: " + red(avgRectColor) + ", " + green(avgRectColor) + ", " + blue(avgRectColor), 10, height - 20); } } // Helper function to calculate average color in a rectangular area color getAverageColor(int x, int y, int w, int h) { int totalR = 0, totalG = 0, totalB = 0; int validPixels = 0; // Loop through every pixel in the rectangle for (int px = x; px < x + w; px++) { for (int py = y; py < y + h; py++) { // Skip pixels outside the camera's bounds if (px >= 0 && px < cam.width && py >= 0 && py < cam.height) { color pixelColor = cam.pixels[py * cam.width + px]; totalR += red(pixelColor); totalG += green(pixelColor); totalB += blue(pixelColor); validPixels++; } } } // Avoid division by zero (in case rectangle is empty/off-screen) if (validPixels == 0) return color(0); // Calculate and return average color return color(totalR/validPixels, totalG/validPixels, totalB/validPixels); }
Quick Additional Checks
- Make sure your rectangle’s
rectWandrectHare greater than 0—if either is 0, you won’t sample any pixels! - If your camera uses a different resolution than your window, adjust the
Captureinitialization to match, or resize the camera feed to window size before loading pixels (usecam.resize(width, height)aftercam.read()).
内容的提问来源于stack exchange,提问作者Hope

