0

我在处理中有一个颜色跟踪程序,它与 Kinect 一起工作。当我单击图片中的某个位置时,它会保存此颜色并在其周围绘制一个椭圆。我只想通过 myPort.write() 将 3 个 int 值(一个用于红色、绿色和蓝色)发送到 Arduino,并将这 3 个值保存在 Arduino 中的 2 个变量中。我的目标是,如果红色变量最高,则点亮红色 LED,如果绿色最高,则点亮绿色 LED,依此类推。

我尝试了几个在谷歌搜索时发现的例子,但没有任何效果。我不知道 Arduino 应该如何在变量中获得正确的值!

编辑:这里有我的处理代码。我从其他几个教程中将它粘在一起,直到我几乎哭了..

    import processing.serial.*;
Serial myPort;

import SimpleOpenNI.*;

SimpleOpenNI kinect;
// Frame
PImage currentFrame;
color trackColor;

int r1, g1, b1, r2, g2, b2;


void setup()
{
  size(640, 480);

  String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, portName, 9600);

  kinect = new SimpleOpenNI(this);
  kinect.enableRGB();

  trackColor = color (255, 0, 0);
  smooth ();

  currentFrame = createImage (640, 480, RGB);
}

void draw()
{
  kinect.update();

  currentFrame = kinect.rgbImage ();
  image(currentFrame, 0, 0);

  currentFrame.loadPixels();

  // Before we begin searching, the "world record" for closest color is set to a high number that is easy for the first pixel to beat.
  float worldRecord = 500;

  // XY coordinate of closest color
  int closestX = 0;
  int closestY = 0;

  // Begin loop to walk through every pixel
  for (int x = 0; x < currentFrame.width; x ++ ) {
    for (int y = 0; y < currentFrame.height; y ++ ) {
      int loc = x + y*currentFrame.width;
      // What is current color
      color currentColor = currentFrame.pixels[loc];
      r1 = (int)red(currentColor);
      g1 = (int)green(currentColor);
      b1 = (int)blue(currentColor);
      r2 = (int)red(trackColor);
      g2 = (int)green(trackColor);
      b2 = (int)blue(trackColor);

      // Using euclidean distance to compare colors
      float d = dist(r1, g1, b1, r2, g2, b2); // We are using the dist( ) function to compare the current color with the color we are tracking.

      // If current color is more similar to tracked color than
      // closest color, save current location and current difference
      if (d < worldRecord) {
        worldRecord = d;
        closestX = x;
        closestY = y;
      }
    }
  }

  // We only consider the color found if its color distance is less than 10.
  // This threshold of 10 is arbitrary and you can adjust this number depending on how accurate you require the tracking to be.
  if (worldRecord < 10) {
    // Draw a circle at the tracked pixel
    fill(trackColor);
    strokeWeight(4.0);
    stroke(0);
    ellipse(closestX, closestY, 30, 30);
  }




  if (mousePressed == true) {
    color c = get(mouseX, mouseY);
    //println("r: " + red(c) + " g: " + green(c) + " b: " + blue(c));

    // Save color where the mouse is clicked in trackColor variable
    int loc = mouseX + mouseY*(currentFrame.width);

    trackColor = currentFrame.pixels[loc];

 println("red " + r2);
 println("green " + g2);
 println("blue " + b2);

 int colors[] = {r2, g2, b2};

 for(int i=0; i < 3; i++) {
   myPort.write(colors[i]); 
 }

} 
 println("ClosestX " + closestX);
  myPort.write(closestX);
}

还有我的 Arduino 代码,我不知道如何获取多个值。

    int val;
int ledPin = 13;
int freq;
int piezoPin = 9;

int redLED = 3;
int greenLED = 5;
int blueLED = 7;

int red, green, blue;

void setup() {
  pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
  Serial.begin(9600); // Start serial communication at 9600 bps

  digitalWrite(ledPin, LOW);
}

void loop() {
  if (Serial.available() > 0)
  { // If data is available to read,
    val = Serial.read(); // read it and store it in val
}

 if(red > green && red > blue) {
 digitalWrite(redLED, HIGH); //light Red LED
 }

  if(green > red && green > blue) {
 digitalWrite(greenLED, HIGH); //light Red LED
 }

 if(blue > red && blue > green) {
 digitalWrite(blueLED, HIGH); //light Red LED
 }


  //Piezo buzzing higher when X-Position of tracked color is higher. 
  if (val < 100) {
    freq = 50;
  }
  else if (val < 200) {
    freq = 200;
  }
  else if (val < 300) {
    freq = 400;
  }
  else if (val < 400) {
    freq = 600;
  }
  else if (val < 500) {
    freq = 800;    
  }
  else (freq = 1000); 

  tone(piezoPin, freq);

}

EDIT2:是的,除了点亮 LED 之外,我还想从压电蜂鸣器发出声音,但这很好用,所以没有任何问题......

请帮忙!!

4

1 回答 1

0

与您的 arduino 的串行通信一次使用一个字节。幸运的是,处理颜色的三个组成部分也是三个字节。

  • 一为红色(0-255)
  • 一为绿色(0-255)
  • 一为蓝色(0-255)

现在我们需要的只是更多信息,以便我们可以将它们分开。

因为一个字节的最小值和最大值是 0-255,所以我们没有可以用来跟踪三个不同字节的安全字符,所以我们需要一种方法来确定我们发送的信息的开始和结束位置。

一个简单的方法是为您的消息设置页眉和页脚;就像是 :

<color>[byte (red)][byte (green)][byte (blue)]</color>

如果我们要读取和解密这样格式的消息,我们将需要一个小缓冲区来存储我们从处理中接收到的值,以便我们可以读回它们,看看我们是否可以匹配消息格式。

所以,在 Arduino 方面,我们需要这个:

String buffer = "";

String messageBegin = "<color>";
String messageEnd = "</color>";


//we read our serial data in the SerialEvent() function
//this is called *after* a loop(), and only if there is serial data in the buffer.
void serialEvent()
{
   while(Serial.available())
   {
       buffer += (char)Serial.read();
   } 
}

void loop() 
{
  //now, inside loop, we no longer need to worry about gathering data from serial.
  //we do still need to figure out if our message is complete, and then parse it.

  //if our buffer contains both the beginning and the end of a message
  //in the right order.
  int beginIndex = buffer.lastIndexOf(messageBegin);
  int endIndex = buffer.lastIndexOf(messageEnd);

  if(beginIndex != -1 && endIndex != -1 && beginIndex < endIndex)
  {
       //we have a complete message!
       //our red color starts 7 characters after where the message begins,
       //because our "messageBegin" is 7 characters long
       string lastMessage = buffer.substring(beginIndex+7);
       //this is arguably not the prettiest way to get our byte values back.
       //see if you can do better for bonus points!
       byte messageAsBytes[80];
       lastMessage.getBytes(messageAsBytes, messageAsBytes.length());

       //we can now finally reconstruct the value we had from processing!
       byte r = (byte)messageAsBytes[0];
       byte g = (byte)messageAsBytes[1];
       byte b = (byte)messageAsBytes[2];

       //if we get a complete message, we can clear our buffer. (don't forget to do this!)
       buffer = "";
  }
}

在处理方面,我们需要做的就是确保我们的 messagebegin 和 messageend 被一起发送:

myPort.write("<color">);
 for(int i=0; i < 3; i++) {
   myPort.write(colors[i]); 
 }
myPort.write("</color">);
于 2015-09-01T13:59:41.683 回答