I tried to convert the code on this url into the code that processing could run.
In order to capture the position of multiple moving pixels with the camera, I completed the conversion of some of the code, but an error occurred on lines 64-66, prompting: Array Index Out of Bounds Exception. I haven’t been able to solve this problem for a long time after trying. I really hope to get your help! Thank you very much!
import processing.video.*;
Capture video;
PImage prev;
PImage img;
ArrayList<FlowZone> fZones;
int nb=20;
float UVCutoff = 3;
void setup() {
size(640, 480, P2D);
video = new Capture(this, width, height, 30 );
video.start();
prev = createImage(width, height, RGB);
}
void captureEvent(Capture video) {
prev.copy(video, 0, 0, video.width, video.height, 0, 0, prev.width, prev.height);
prev.updatePixels();
video.read();
}
void draw() {
video.loadPixels();
prev.loadPixels();
loadPixels();
image(video, 0, 0);
ArrayList<FlowZone> fZones = calculateFlow (video.width, video.height);
for (FlowZone fz : fZones) {
fz.draw();
}
updatePixels();
}
ArrayList<FlowZone> calculateFlow(int width, int height) {
ArrayList<FlowZone> zones = new ArrayList();
if (prev.pixels == null)
return zones;
int step = 8;
int winStep = step * 2 + 1;
int A2, A1B2, B1, C1, C2;
int u, v;
int wMax = width - step - 1;
int hMax = height - step - 1;
int globalY, globalX, localY, localX;
for ( globalY = step + 1; globalY < hMax; globalY += winStep)
{
for ( globalX = step + 1; globalX < wMax; globalX += winStep)
{
A2 = A1B2 = B1 = C1 = C2 = 0;
for ( localY = -step; localY <= step; localY++)
{
for ( localX = -step; localX <= step; localX++)
{
int address = (globalY + localY) * width + globalX + localX;
float gradX = (video.pixels[(address - 1) * 4]) - (video.pixels[(address + 1) * 4]);
float gradY = (video.pixels[(address - width) * 4]) - (video.pixels[(address + width) * 4]);
float gradT = (prev.pixels[address * 4]) - (video.pixels[address * 4]);
A2 += gradX * gradX;
A1B2 += gradX * gradY;
B1 += gradY * gradY;
C2 += gradX * gradT;
C1 += gradY * gradT;
}
}
int delta = (A1B2 * A1B2 - A2 * B1);
if (delta != 0) {
/* system is not singular - solving by Kramer method */
int Idelta = step / delta;
int deltaX = -(C1 * A1B2 - C2 * B1);
int deltaY = -(A1B2 * C2 - A2 * C1);
u = deltaX * Idelta;
v = deltaY * Idelta;
} else
{
/* singular system - find optical flow in gradient direction*/
int norm = (A1B2 + A2) * (A1B2 + A2) + (B1 + A1B2) * (B1 + A1B2);
if (norm != 0)
{
int IGradNorm = step / norm;
int temp = -(C1 + C2) * IGradNorm;
u = (A1B2 + A2) * temp;
v = (B1 + A1B2) * temp;
} else
{
u = v = 0;
}
}
if (-winStep < u && u < winStep &&
-winStep < v && v < winStep) {
zones.add(new FlowZone(globalX, globalY, u, v));
}
}
}
return zones;
}
class FlowZone {
public float X, Y, U, V;
public FlowZone(float x, float y, float u, float v) {
X = x;
Y = y;
U = u;
V = v;
}
public void draw() {
if ((abs(U) + abs(V)) / 2.0 < UVCutoff) return;
pushMatrix();
pushStyle();
stroke(255);
fill(0, 0, 0, 80);
line(X, Y, U*3, V*3);
popStyle();
popMatrix();
}
}