It is written in C++ and uses the OpenCV library to read and display images.
The parent process writes to the FPGA, the child then reads the result from FPGA and sends it back to the parent via a named fifo.
This code is given below:
- Code: Select all
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
using namespace cv;
using namespace std;
int i = 0;
VideoCapture cap(0);
void ChildProcess(void); /* child process prototype */
void ParentProcess(void); /* parent process prototype */
int main()
{
pid_t pid;
pid = fork();
if (pid != 0)
ChildProcess();
else
ParentProcess();
}
void ChildProcess(void)
{
int fd2 = open("/dev/xillybus_read_32",O_RDONLY);
if (fd2 < 1)
{
perror("open error");
}
for(;;)
{
///Read result from FPGA--500*500 bytes array///
int rows = 500;
int cols = 500;
int nchan = 1;
int totalbytes = rows*cols*nchan;
int buflen = cols*nchan;
int ret;
uchar buf[buflen];
uchar datarray[totalbytes];
Mat img(rows,cols,CV_8UC1);
int j;
int k = 0;
int bread = 0;
while(bread<totalbytes)
{
ret=read(fd2,buf,buflen);
for ( j = 0 ; j<= (ret-1);j++ )
{
datarray[j+k] = buf[j];
}
k = k+ret;
bread = bread+ret;
}
img.data = datarray;
cout<<"Fpga receive succeeded"<<endl;
close(fd2);
int fd3 = open("/root/vidpipe",O_WRONLY);
if (fd3 < 1)
{
perror("open error");
}
totalbytes = img.total()*img.elemSize();
buflen = (img.cols);
uchar *framepointer = img.data;
int bwritten = 0;
int ret2;
uchar* buf2;
buf2 = framepointer;
while(bwritten<totalbytes)
{
ret2 = write(fd3,buf2,buflen);
buf2 = buf2 + ret2;
bwritten = bwritten+ret2;
}
cout<<"child to parent send succeeded"<<endl;
close(fd3);
}
}
void ParentProcess(void)
{
int check;
int fd;
int totalbytes;
int buflen;
int count = 0;
fd = open("/dev/xillybus_write_32",O_WRONLY);
if (fd < 1)
{
perror("open error");
}
for(;;)
{
i++;
cout<<"iteration "<<i<<endl;
Mat frame;
cap >> frame;
frame = frame(Rect(10,10,500,500));
totalbytes = frame.total()*frame.elemSize();
buflen = (frame.cols);
uchar *framepointer = frame.data;
int bwritten = 0;
int ret;
uchar* buf;
buf = framepointer;
int num = totalbytes/buflen;
while(bwritten<totalbytes)
{
ret = write(fd,buf,buflen);
write(fd,NULL,0);
buf = buf + ret;
bwritten = bwritten+ret;
cout<<"--------Loop1--------"<<endl;
}
///Receive processed frame from FPGA///
int rows = 500;
int cols = 500;
int nchan = 1;
totalbytes = rows*cols*nchan;
int ret2;
int fd1 = open("/root/vidpipe",O_RDONLY);
if (fd1 < 1)
{
perror("open error");
}
uchar buf2[buflen];
uchar datarray[totalbytes];
Mat img(rows,cols,CV_8UC1);
int j;
int k = 0;
int bread = 0;
while(bread<totalbytes)
{
ret2=read(fd1,buf2,buflen);
for ( j = 0 ; j<= (ret-1);j++ )
{
datarray[j+k] = buf2[j];
}
k = k+ret2;
bread = bread+ret2;
}
img.data = datarray;
close(fd1);
for( int p = 1; p <= img.rows; p++ )
{
for( int q = 1; q <= img.cols; q++ )
{
if( img.at<uchar>(p,q) == 1 )
{
circle( frame, Point( p, q ), 5, Scalar(255,0,0), 2, 8, 0 );
}
}
}
cout<<"Process frame receive succeeded"<<endl;
imshow( "Received image in parent", frame );
waitKey(1);
cout<<"--------Parent Ended --------"<<endl;
}
}
This code works fine on a single image(500*500*3 RGB image).I tested it on a chessboard image and the result was a set of corners which I overlayed on the original image.Now, my actual goal is to use a stream of images from a webcam and overlay the resulting corners from the FPGA(500*500 binary image, with 1's representing corners on the image).
Here, comes the problem: The webcam stream runs for a while and then freezes and the process appears as if it is blocking on the terminal(with the cursor blinking of course).
The interesting thing is that for a given resolution like 500*500 or 640*480,it runs for a unique number of iterations and then blocks.Sometimes, the process appears to terminate and when I restart it, it starts from the same number of iterations where it stopped.This has left me really confused.
Now, I cannot find what's wrong with what I am doing here.
Is it because my FPGA cannot keep up with the data rate or the fifos are full etc?
Or is it because the process running on linux eats up all resources?
Or if there is a way I am using the child and parent process that messes up everything?
I have tried changing to smaller resolution for the stream and this makes it run for more iterations but then it freezes eventually.I have tried changing buffer length but this has no effect on the process.
Please, give me a hint as to what I should try? My C + system programming + FPGA skills are of intermediate level.I will explore any possible hint from your side to improve it.I am stuck on it for weeks now.