如何在处理中对更多帧的值取平均值
How to average values of more frames in Processing
我正在编写此代码来管理和保存来自 Microsoft kinect 的数据,数据存储在 int 数组 int[] depthValues 中,我想做的是存储和保存平均值更多帧(假设为 10),以获得更平滑的数据,将代码的其余部分保持原样。
代码如下:
import java.io.File;
import SimpleOpenNI.*;
import java.util.*;
SimpleOpenNI kinect;
void setup()
{
size(640, 480);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
}
int precedente = millis();
void draw()
{
kinect.update();
PImage depthImage = kinect.depthImage();
image(depthImage, 0, 0);
int[] depthValues = kinect.depthMap();
StringBuilder sb = new StringBuilder();
Deque<Integer> row = new LinkedList<Integer>();
int kinectheight = 770; // kinect distance from the baselevel [mm]
int scaleFactor = 1;
int pixelsPerRow = 640;
int pixelsToSkip = 40;
int rowNum = 0;
for (int i = 0; i < depthValues.length; i++) {
if (i > 0 && i == (rowNum + 1) * pixelsPerRow) {
fillStringBuilder(sb, row);
rowNum++;
sb.append("\n");
row = new LinkedList<Integer>();
}
if (i >= (rowNum * pixelsPerRow) + pixelsToSkip) {
row.addFirst((kinectheight - depthValues[i]) * scaleFactor);
}
}
fillStringBuilder(sb, row);
String kinectDEM = sb.toString();
final String[] txt= new String[1]; //creates a string array of 2 elements
int savingtimestep = 15000; // time step in millisec between each saving
if (millis() > precedente + savingtimestep) {
txt[0] = "ncols 600\nnrows 480\nxllcorner 0\nyllcorner 0\ncellsize 91.6667\nNODATA_value 10\n" +kinectDEM;
saveStrings("kinectDEM0.tmp", txt);
precedente = millis();
// delete the old .txt file, from kinectDEM1 to kinectDEMtrash
File f = new File (sketchPath("kinectDEM1.txt"));
boolean success = f.delete();
// rename the old .txt file, from kinectDEM0 to kinectDEM1
File oldName1 = new File(sketchPath("kinectDEM0.txt"));
File newName1 = new File(sketchPath("kinectDEM1.txt"));
oldName1.renameTo(newName1);
// rename kinectDEM0.tmp file to kinectDEM0.txt
File oldName2 = new File(sketchPath("kinectDEM0.tmp"));
File newName2 = new File(sketchPath("kinectDEM0.txt"));
oldName2.renameTo(newName2);
}
}
void fillStringBuilder(StringBuilder sb, Deque<Integer> row) {
boolean emptyRow = false;
while (!emptyRow) {
Integer val = row.pollFirst();
if (val == null) {
emptyRow = true;
} else {
sb.append(val);
val = row.peekFirst();
if (val != null) {
sb.append(" ");
}
}
}
}
您有一个名为 depthValues
的 int[]
数组变量。您可以像使用任何其他值一样使用此值。换句话说,您可以创建一个包含多个 int[]
值的 array
或 ArrayList
。
以下是您可以如何使用 ArrayList
来保存以前的值:
ArrayList<int[]> previousDepthValues = new ArrayList<int[]>();
void draw(){
//add current depth map to ArrayList
previousDepthValues.add(kinect.depthMap());
//limit the ArrayList to hold 10 values
if(previousDepthValues.size() == 11){
previousDepthValues.remove(0);
}
//create an array to hold the averaged values
int[] averageDepthValues = new int[previousDepthValues.get(0).length];
//loop over the 10 previous depth values in the ArrayList
for(int[] depthValue : previousDepthValues){
//loop over the ints in each previous depth values array
for(int i = 0; i < averageDepthValues.length; i++){
//add all of the values up
averageDepthValues[i] += depthValue[i];
}
}
//divide each number to get the average
for(int i = 0; i < averageDepthValues.length; i++){
averageDepthValues[i] /= averageDepthValues.length;
}
//averageDepthValues now holds the average of the last 10 frames
}
我正在编写此代码来管理和保存来自 Microsoft kinect 的数据,数据存储在 int 数组 int[] depthValues 中,我想做的是存储和保存平均值更多帧(假设为 10),以获得更平滑的数据,将代码的其余部分保持原样。
代码如下:
import java.io.File;
import SimpleOpenNI.*;
import java.util.*;
SimpleOpenNI kinect;
void setup()
{
size(640, 480);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
}
int precedente = millis();
void draw()
{
kinect.update();
PImage depthImage = kinect.depthImage();
image(depthImage, 0, 0);
int[] depthValues = kinect.depthMap();
StringBuilder sb = new StringBuilder();
Deque<Integer> row = new LinkedList<Integer>();
int kinectheight = 770; // kinect distance from the baselevel [mm]
int scaleFactor = 1;
int pixelsPerRow = 640;
int pixelsToSkip = 40;
int rowNum = 0;
for (int i = 0; i < depthValues.length; i++) {
if (i > 0 && i == (rowNum + 1) * pixelsPerRow) {
fillStringBuilder(sb, row);
rowNum++;
sb.append("\n");
row = new LinkedList<Integer>();
}
if (i >= (rowNum * pixelsPerRow) + pixelsToSkip) {
row.addFirst((kinectheight - depthValues[i]) * scaleFactor);
}
}
fillStringBuilder(sb, row);
String kinectDEM = sb.toString();
final String[] txt= new String[1]; //creates a string array of 2 elements
int savingtimestep = 15000; // time step in millisec between each saving
if (millis() > precedente + savingtimestep) {
txt[0] = "ncols 600\nnrows 480\nxllcorner 0\nyllcorner 0\ncellsize 91.6667\nNODATA_value 10\n" +kinectDEM;
saveStrings("kinectDEM0.tmp", txt);
precedente = millis();
// delete the old .txt file, from kinectDEM1 to kinectDEMtrash
File f = new File (sketchPath("kinectDEM1.txt"));
boolean success = f.delete();
// rename the old .txt file, from kinectDEM0 to kinectDEM1
File oldName1 = new File(sketchPath("kinectDEM0.txt"));
File newName1 = new File(sketchPath("kinectDEM1.txt"));
oldName1.renameTo(newName1);
// rename kinectDEM0.tmp file to kinectDEM0.txt
File oldName2 = new File(sketchPath("kinectDEM0.tmp"));
File newName2 = new File(sketchPath("kinectDEM0.txt"));
oldName2.renameTo(newName2);
}
}
void fillStringBuilder(StringBuilder sb, Deque<Integer> row) {
boolean emptyRow = false;
while (!emptyRow) {
Integer val = row.pollFirst();
if (val == null) {
emptyRow = true;
} else {
sb.append(val);
val = row.peekFirst();
if (val != null) {
sb.append(" ");
}
}
}
}
您有一个名为 depthValues
的 int[]
数组变量。您可以像使用任何其他值一样使用此值。换句话说,您可以创建一个包含多个 int[]
值的 array
或 ArrayList
。
以下是您可以如何使用 ArrayList
来保存以前的值:
ArrayList<int[]> previousDepthValues = new ArrayList<int[]>();
void draw(){
//add current depth map to ArrayList
previousDepthValues.add(kinect.depthMap());
//limit the ArrayList to hold 10 values
if(previousDepthValues.size() == 11){
previousDepthValues.remove(0);
}
//create an array to hold the averaged values
int[] averageDepthValues = new int[previousDepthValues.get(0).length];
//loop over the 10 previous depth values in the ArrayList
for(int[] depthValue : previousDepthValues){
//loop over the ints in each previous depth values array
for(int i = 0; i < averageDepthValues.length; i++){
//add all of the values up
averageDepthValues[i] += depthValue[i];
}
}
//divide each number to get the average
for(int i = 0; i < averageDepthValues.length; i++){
averageDepthValues[i] /= averageDepthValues.length;
}
//averageDepthValues now holds the average of the last 10 frames
}