CTS Application Notes 1.0
CTS Application Notes 1.0
CTS Application Notes 1.0
Application notes
Compact all in one solution to add vision to your project.
Revision History
Date
Version
01/24/2013 V1.0
Author
Claudiu G.
Description
Initial release
References
[1] Online documentation: http://thinksmallthings.wordpress.com
[2] Processing: http://www.processing.org
Index
1 Introduction ............................................................................................... 5
2 Streaming .................................................................................................. 6
2.1 Image Data format ................................................................................... 6
2.2 Using Processing ..................................................................................... 6
2.3 YUV422 .................................................................................................... 7
2.4 YUV211 .................................................................................................... 8
2.5 B&W ......................................................................................................... 9
3 Tracking ................................................................................................... 10
3.1 Data format ............................................................................................. 10
3.2 Fast Tracking .......................................................................................... 10
3.3 Tracking multiple blobs ........................................................................... 11
4 Appendix.................................................................................................. 13
Copyright/Licensing/Disclaimer Info
CTS hardware Copyright 2013 Claudiu Georgescu
CTS Client PC Software Copyright 2013 Claudiu Georgescu
All material in this document is Copyright 2013 by Claudiu Georgescu
Both CTS and CTS Client PC software are licensed under the GNU General
Public License. If interested in an alternative licensing scheme, please contact
Claudiu Georgescu @ http://thinksmallthings.wordpress.com.
The CTS solution is distributed in the hope that it will be useful. However, no
warranties, either expressed or implied, are made regarding the operation,
use or results of this system. The CTS should not be used in any life-critical
applications.
1 Introduction
This document covers details on how to access and use CTS module within
an application. For convenience PROCESSING was used in most of the
examples within this document.
2 Streaming
One of the CTS features is the ability to capture and stream data to a client
over serial link.
void setup(){
println(Serial.list());
myPort = new Serial(this, "/dev/cu.usbserial-A800GKF2", 115200);
size(320, 240);
delay(500);
delay(50);
// CTS: Set image resolution to QVGA
myPort.write("r0");
delay(50);
// CTS: Set image orientation
myPort.write("fn");
delay(50);
// CTS: Set image brightness
myPort.write("b2");
delay(50);
// CTS: Set image contrast
myPort.write("c4");
delay(50);
// CTS: Set image saturation
myPort.write("s4");
delay(50);
// CTS: Set image gamma
myPort.write("g5");
delay(50);
// CTS: Set image white balance
myPort.write("a1");
delay(50);
// CTS: Set image sharpness
myPort.write("Sd");
delay(50);
// CTS: Set learning box width and height
myPort.write("Lb281e");
delay(50);
// CTS: initiate training for color class 0
myPort.write("Lc0");
delay(50);
}
int unsignedByte( int val ) {
return ( val < 0 ? 256+val : val );
}
2.3 YUV422
Bellow is the code to capture and display a frame in YUV422 format:
void draw() {
int x = 0;
int y = 0;
float R, G, B;
int
int
int
int
Y = 0;
Y1 = 0;
U = 0;
V = 0;
myPort.write("FY4");
while (myPort.available() > 0){
&
&
&
&
0xFF;
0xFF;
0xFF;
0xFF;
pixel n
- 128);
- 128) - 0.391*(U - 128);
- 128);
fill(R, G, B);
rect(x*2, y, 1, 1);
// Calculate RGB from YUV, pixel n + 1
B= 1.164*(Y1 - 16) + 2.018*(U - 128);
G = 1.164*(Y1 - 16) - 0.813*(V - 128) - 0.391*(U - 128);
R = 1.164*(Y1 - 16) + 1.596*(V - 128);
fill(R, G, B);
rect(x*2+1, y, 1, 1);
}
}
}
myPort.clear();
}
}
2.4 YUV211
Bellow is the code to capture and display a frame in YUV211 format:
void draw
int pos
int x =
int y =
() {
= 0;
0;
0;
float R = 0;
float G = 0;
float B = 0;
int
int
int
int
Y = 0;
Y1 = 0;
U = 0;
V = 0;
myPort.write("FY2");
while (myPort.available() > 0){
byte[] inBuffer = new byte[H*W+4];
// Read image from serial port
myPort.readBytes(inBuffer);
if ((inBuffer != null) && (inBuffer[0] == 0x46) && (inBuffer[1] == 0)){
for (y=0;y<H;y++){
for (x=0;x<W/2;x++){
noStroke();
colorMode(RGB, 255);
// Prepare YUV values
Y = inBuffer[y*W+x*2+3]
U = (inBuffer[y*W+x*2+3]
Y1= inBuffer[y*W+x*2+3+1]
V = (inBuffer[y*W+x*2+3+1]
&
&
&
&
0xF0;
0x0F) << 4;
0xF0;
0x0F) << 4;
2.5 B&W
Bellow is the code to capture and display a frame in B&W format:
void draw() {
int pos = 0;
int x = 0;
int y = 0;
int pixel = 0;
int Y = 0;
int Y1 = 0;
myPort.write("FYb");
while (myPort.available () > 0) {
byte[] inBuffer = new byte[H*(W/2)+5];
// Read image from serial port
myPort.readBytes(inBuffer);
if ((inBuffer != null) && (inBuffer[0] == 0x46) && (inBuffer[1] == 0)) {
for (y=0;y<H;y++) {
for (x=0;x<W/2;x++) {
noStroke();
colorMode(RGB, 255);
pixel = inBuffer[y*(W/2)+x+3] & 0xFF;
// calculate pixel values
Y = pixel & 0xF0;
Y1 =(pixel & 0x0F) << 4;
// Display pixel n
fill(Y);
rect(2*x, y, 1, 1);
// Display pixel n + 1
fill(Y1);
rect(x*2+1, y, 1, 1);
}
}
}
myPort.clear();
}
}
3 Tracking
While in Tracking mode, CTS may return tracking information and image data.
For image data, same code as in Streaming section (Chapter 2) and will not
be discussed here.
As a rule, the image data if enabled will always be streamed first and then the
tracking information (data format is explained in details in CTS module User
Manual document).
Byte1:
Byte2:
Byte3:
Byte4:
Byte5:
Byte6:
Byte7:
Byte8:
Byte9:
Byte1:
Byte2:
Byte3:
Byte4:
Byte5:
Tracking, no blob:
Start byte (0x42)
Start byte (0x00)
0x00
End byte (0x00)
End byte (0xFF)
void draw() {
int pos = 0;
int x = 0;
int y = 0;
int pixel = 0;
int Y = 0;
int Y1 = 0;
myPort.write("TF0");
while (myPort.available () > 0) {
byte[] preBuffer = new byte[3];
myPort.readBytes(preBuffer);
println(">>"+preBuffer[2]);
if ((preBuffer[0] == 66) && (preBuffer[1] == 0x00)
byte[] blobBuffer = new byte[7];
myPort.readBytes(blobBuffer);
Or using C:
if (savailable()){
c = sgetc();
if (c == 0x42){
c = sgetc();
c = sgetc();
if (c == 0x01){
i = 0;
for(i=0;i<7;i++){
buf[i] = sgetc();
}
// retrieve COG X, COG Y and
cogX
= ((buf[0] & 0x07) <<
cogY
= ((buf[2] & 0x07) <<
weight = (buf[4] & 0x7f);
} else {
// reset values if no target
cogX = 0;
cogY = 0;
weight = 0;
}
// Your code
}
}
int pos = 0;
int x = 0;
int y = 0;
int pixel = 0;
int Y = 0;
int Y1 = 0;
myPort.write("TCt");
while (myPort.available () > 0) {
byte[] preBuffer = new byte[3];
myPort.readBytes(preBuffer);
if ((preBuffer[0] == 0x42) && (preBuffer[1] == 0x00)) {
byte counter = preBuffer[2];
for (x = 0; x < counter; x++) {
byte[] blobBuffer = new byte[14];
myPort.readBytes(blobBuffer);
int
int
int
int
int
int
int
int
id
=
weight=
cogx =
cogy =
topX =
topY =
botX =
botY =
blobBuffer[0];
unsignedByte(blobBuffer[5]);
unsignedByte(blobBuffer[1] << 8) + unsignedByte(blobBuffer[2]);
unsignedByte(blobBuffer[3] << 8) + unsignedByte(blobBuffer[4]);
unsignedByte(blobBuffer[6] << 8) + unsignedByte(blobBuffer[7]);
unsignedByte(blobBuffer[8] << 8) + unsignedByte(blobBuffer[9]);
unsignedByte(blobBuffer[10] << 8) + unsignedByte(blobBuffer[11]);
unsignedByte(blobBuffer[12] << 8) + unsignedByte(blobBuffer[13]);
noFill();
strokeWeight(2);
stroke (0, 0, 0);
rect((topX-2) * m, (topY-1) * m, (botX - topX+1) * m, (botY - topY+1) * m);
fill (0, 0, 0);
rect ((cogx - 3)* m, (cogy -3)*m, 6*m, 6*m);
}
}
myPort.clear();
}
}
4 Appendix
Code for streaming YUV211 frame and displaying tracking boxes for multiple
blobs:
import processing.serial.*;
String myString = null;
Serial myPort;
PFont f;
void setup() {
println(Serial.list());
myPort = new Serial(this, "/dev/cu.usbserial-A800GKF2", 921600);
size(W * m, H * m+20);
delay(500);
delay(50);
myPort.write("fn");
delay(50);
myPort.write("b2");
delay(50);
myPort.write("c4");
delay(50);
myPort.write("s4");
delay(50);
myPort.write("g5");
delay(50);
myPort.write("a1");
delay(50);
myPort.write("Sd");
delay(50);
}
void draw() {
int pos = 0;
int x = 0;
int y = 0;
float R = 0;
float G = 0;
float B = 0;
int
int
int
int
Y = 0;
Y1 = 0;
U = 0;
V = 0;
myPort.write("TCy");
while (myPort.available () > 0) {
byte[] inBuffer = new byte[H*W+4];
myPort.readBytes(inBuffer);
if ((inBuffer != null) && (inBuffer[1] == 0)) {
for (y=0;y<H;y++) {
for (x=0;x<W/2;x++) {
noStroke();
colorMode(RGB, 255);
Y = inBuffer[y*W+x*2+3]
& 0xF0;
U = (inBuffer[y*W+x*2+3]
& 0x0F) << 4;
Y1= inBuffer[y*W+x*2+3+1] & 0xF0;
V = (inBuffer[y*W+x*2+3+1] & 0x0F) << 4;
B = 1.164*(Y - 16) + 2.018*(U - 128);
G = 1.164*(Y - 16) - 0.813*(V - 128) - 0.391*(U - 128);
R = 1.164*(Y - 16) + 1.596*(V - 128);
fill(R, G, B);
rect(2*x, y, 1, 1);
B= 1.164*(Y1 - 16) + 2.018*(U - 128);
G = 1.164*(Y1 - 16) - 0.813*(V - 128) - 0.391*(U - 128);
R = 1.164*(Y1 - 16) + 1.596*(V - 128);
fill(R, G, B);
rect(x*2+1, y, 1, 1);
}
}
}
byte[] preBuffer = new byte[3];
myPort.readBytes(preBuffer);
if ((preBuffer[0] == 0x42) && (preBuffer[1] == 0x00)) {
byte counter = preBuffer[2];
for (x = 0; x < counter; x++) {
byte[] blobBuffer = new byte[14];
myPort.readBytes(blobBuffer);
int
int
int
int
int
int
int
int
id
=
weight=
cogx =
cogy =
topX =
topY =
botX =
botY =
blobBuffer[0];
unsignedByte(blobBuffer[5]);
unsignedByte(blobBuffer[1] << 8) + unsignedByte(blobBuffer[2]);
unsignedByte(blobBuffer[3] << 8) + unsignedByte(blobBuffer[4]);
unsignedByte(blobBuffer[6] << 8) + unsignedByte(blobBuffer[7]);
unsignedByte(blobBuffer[8] << 8) + unsignedByte(blobBuffer[9]);
unsignedByte(blobBuffer[10] << 8) + unsignedByte(blobBuffer[11]);
unsignedByte(blobBuffer[12] << 8) + unsignedByte(blobBuffer[13]);
noFill();
strokeWeight(2);
stroke (0, 0, 0);
rect((topX-2) * m, (topY-1) * m, (botX - topX+1) * m, (botY - topY+1) * m);
fill (0, 0, 0);
rect ((cogx - 3)* m, (cogy -3)*m, 6*m, 6*m);
}
}
myPort.clear();
}
}
int unsignedByte( int val ) {
return ( val < 0 ? 256+val : val );
}