The source code is posted on google code. You can download it straight from the interwebs with beagleboard. Download the folder, run the Makefile, run ./slGPIO.cpp, and push the button to start scanning! Once completed if the program finds a usbdrive it will save the point cloud there. If not it will be saved in the results folder.
Contents
- Graycoded Structured Light images [20]
- Makefile // includes links to openCV cflags and libs. Use this to natively compile SL code.
- sl.cpp //sl program
- slGPIO.cpp // starting point. Initializes GPIO interrupt and calls sl.cpp
- results folder //result go here if no SDcard is found
# 'make' build executable file 'mycc' # 'make clean' removes all .o and executable files .PHONY: depend clean SCAN = slGPIO DISPLAY = display CC = gcc CFLAGS := -g -Wall -DLINUX $(shell pkg-config opencv --cflags) LIBs := $(shell pkg-config opencv --libs) LFLAGS = # Source files SRCs := \ slGPIO.cpp #sl.cpp \ # List of object files to compile OBJs = $(SRCs:.cpp=.o) all: $(SCAN) $(DISPLAY): display.o gcc -g -Wall $(SCAN): $(OBJs) $(CC) $(CFLAGS) $(INCLUDES) -o $(SCAN) $(OBJs) $(LFLAGS) $(LIBs) # cp $(SCAN) Release/ %.o: %.cpp %.h $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ clean: $(RM) *.o *~ $(SCAN)
The sl code was written by myself and Peter Hokanson. Its not to long and is broken up into 3 sections. The source code will likely be easier to read with proper highlighting. OpenCV was only used to manipulate the camera and projector. Part 1 below projects and captures the images:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h> // For my own paranoia's sake
#include <opencv/cv.h>
#include <opencv/highgui.h>
#define WHITE_THRESHOLD 5
#define BLACK_THRESHOLD -5
#define NUM_IMAGES 18
#define CAM_WIDTH 640
#define PROJ_WIDTH 640
#define Z_SCALE 500 //250 works
//#define TEST_RECOGNIZER
int gray2bin(int gray);
bool file_exists(const char * filename);
int slScanner(void);
int slScanner(void)
{
//*********PART1 - Project SL and Cap Imgs************
//Initialize
IplImage* slPat[NUM_IMAGES] = {0};
IplImage* capImg[NUM_IMAGES + 1] = {0};
// int height,width,step,channels;
uchar *data;
char s[128];
int i,outFileNum=0;
//Usage
//if(argc>1){
// printf("Usage: sl images are in same folder named grayIMGx.png and range from 0-19\n");
// exit(0);
//}
//Load sl images
#ifndef TEST_RECOGNIZER
for(int i=0;i<NUM_IMAGES;i++){
sprintf(s,"%d.png",i+1);
slPat[i]=cvLoadImage(s);
if(!slPat[i]){
printf("Could not load image file: %s\n",s);
exit(0);
}
}
// create a window
cvStartWindowThread();
cvNamedWindow("mainWin", CV_WINDOW_NORMAL);
cvSetWindowProperty("mainWin", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
// pause
cvWaitKey(500);
// set up camera
CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
if (!capture){
fprintf( stderr, "Camera not found \n");
getchar();
exit(0);
}
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640);
//cvSetCaptureProperty(capture, CV_CAP_PROP_FPS, 5);
//cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT, 1);
//Maybe this will fix the frame delay?
//Display images and capture
for(int i=0;i<NUM_IMAGES;i++){
// show the image
cvShowImage("mainWin", slPat[i] );
// pause
cvWaitKey(5);
// capture the image
cvGrabFrame(capture);
cvGrabFrame(capture);
cvGrabFrame(capture);
cvGrabFrame(capture);
cvGrabFrame(capture); //Get to last frame in buffer
capImg[NUM_IMAGES + 1] = cvRetrieveFrame(capture);
// write the image
//cvWriteFrame(writer, capImg[i]);
capImg[i] = cvCloneImage(capImg[NUM_IMAGES + 1]);
sprintf(s,"results/%d.png",i+1);
cvSaveImage(s,capImg[i]);
}
cvReleaseCapture(&capture);
//Display captured images for debug
for(int i=0;i<NUM_IMAGES;i++){
// show the image (for debug)
cvShowImage("mainWin", capImg[i] );
// pause
cvWaitKey(100);
}
#else // TEST_RECOGNIZER
for(int i=0;i<NUM_IMAGES;i++) {
sprintf(s,"setupp/%d.png",i+1);
capImg[i]=cvLoadImage(s);
if(!capImg[i]){
printf("Could not load image file: %s\n",s);
exit(0);
}
}
#endif
Part 2 contains the SL decoding and depth redering algorithm:
//*********PART2 - Decode captured images************
// First initialize a matrix for showing the decoded values, needs 10 bits,
// so could move to short* if memory becomes an issue.
int *columnmap = (int*)calloc(capImg[0]->imageSize, sizeof(int));
if(columnmap == NULL) {
printf("Allocation for column map failed! Aborting\n");
return 1;
}
// We're going to step over matching inverse pairs of projected patterns, and
// perform a threshold operation to determine whether a given pixel is white
// or not.
for(int i=0;i<NUM_IMAGES;i+=2){
printf("Processing scan patterns %d, %d\n",i,i+1);
uchar* data1 = (uchar*)capImg[i]->imageData;
uchar* data0 = (uchar*)capImg[i+1]->imageData;
for(int y=0;y<capImg[i]->height;y++){
for(int x=0;x<capImg[i]->width;x++) {
int u = y*capImg[i]->widthStep+x*capImg[i]->nChannels;
if(columnmap[u] == -1){
// We have discarded this pixel
continue;
}
int gray1 = data1[u] + data1[u+1] + data1[u+2];
int gray0 = data0[u] + data0[u+1] + data0[u+2];
// Shift our Gray code bit vector
columnmap[u] = columnmap[u] << 1;
if(gray1 - gray0 > WHITE_THRESHOLD){
// We have a white pixel!
assert((columnmap[u] & 1) == 0);
columnmap[u] |= 1;
} else if(gray1 - gray0 < BLACK_THRESHOLD){
// A black pixel
assert((columnmap[u] & 1) == 0);
columnmap[u] |= 0;
} else {
// Not quite sure about this pixel: Punt!
columnmap[u] = -1;
}
}
}
// Avoid memory leaks!
// printf("Releasing images %d, %d\n", i,i+1);
// cvReleaseImage(&capImg[i]);
// cvReleaseImage(&capImg[i+1]);
}
// Convert Gray code to decimal
for(i = 0; i < capImg[0]->imageSize; i++){
// int tmp = columnmap[i];
columnmap[i] = gray2bin(columnmap[i]);
// printf("Gray: %4x -> Binary %4x\n",tmp,columnmap[i]);
}
// TODO: Test against projector patterns -> 0 disparity
// TODO: Test with SL images
//Find available filename on jumpdrive
sprintf(s,"/media/sda1/result%d.xyz",outFileNum);
while (file_exists(s)) {
outFileNum++;
sprintf(s,"/media/sda1/result%d.xyz",outFileNum);
}
// Write the pointcloud
FILE *f = fopen(s,"w");
if(f == NULL) {
printf("Error opening %s: Trying local directory...\n",s);
FILE *f = fopen("result.xyz","w");
if(f == NULL) {
printf("Error opening result.xyz: Aborting!\n");
return 1;
}
}
printf("Writing pointcloud...\n");
for(int y = 0;y < capImg[0]->height; y++){
for(int x = 0;x < capImg[0]->width; x++) {
int u = y*capImg[0]->widthStep+x*capImg[0]->nChannels;
if(columnmap[u] == -1) continue; // Discarded!
float disp = (float)columnmap[u]/(PROJ_WIDTH) - (float)x/CAM_WIDTH;
// printf("%f\n",disp);
if(disp == 0.0) continue;
float z = (float)Z_SCALE/(disp);
fprintf(f,"%d %d %f\n",x,y,z);
}
}
fclose(f);
Part 3 is a work in progress. All thats contained here is some cleanup.
//*******Part3 - Project 3D object with openGL*********
for(int i = 0; i < NUM_IMAGES; i++){
cvReleaseImage(&capImg[i]);
//cvReleaseImage(&slPat[i]);
}
//Exit
cvDestroyWindow("mainWin");
free(columnmap);
return 0;
}
<–Previous Project Home Next –>

When I run the slGPIO command it says starting scanning then quickly gives up with a gtk error cant find display
I have the same setup as you have here, other than my switch is just 2 pins joined together and my camera is the 5mp one which seems to be working ok