Commit 5f69c318 authored by Miklós Homolya's avatar Miklós Homolya

camera integration

parent 06544d14
#include "glwidget.h"
#include "kernel.h"
#include <QGLFunctions>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cuda_runtime_api.h>
#include <cuda_gl_interop.h>
#include <cstdio>
GLuint positionsVBO;
struct cudaGraphicsResource* positionsVBO_CUDA;
GlWidget::GlWidget(QWidget *parent)
: QGLWidget(QGLFormat(), parent), func(context()), start(time(NULL))
{
}
GlWidget::~GlWidget()
{
}
QSize GlWidget::sizeHint() const
{
return QSize(640, 480);
}
void GlWidget::initializeGL()
{
makeCurrent();
// Explicitly set device 0
cudaGLSetGLDevice(0);
// Create buffer object and register it with CUDA
func.glGenBuffers(1, &positionsVBO);
func.glBindBuffer(GL_PIXEL_UNPACK_BUFFER, positionsVBO);
size_t size = (size_t)640 * 480 * 4 * sizeof(unsigned char); // TODO
func.glBufferData(GL_PIXEL_UNPACK_BUFFER, size, 0, GL_DYNAMIC_DRAW);
//func.glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); // TODO: what is it?
cudaGraphicsGLRegisterBuffer(&positionsVBO_CUDA, positionsVBO, cudaGraphicsMapFlagsWriteDiscard);
}
void GlWidget::paintGL()
{
// Map buffer object for writing from CUDA
unsigned char *positions;
cudaGraphicsMapResources(1, &positionsVBO_CUDA, 0);
size_t num_bytes;
cudaGraphicsResourceGetMappedPointer((void**)&positions, &num_bytes, positionsVBO_CUDA);
float *d_in;
cudaMalloc((void **)&d_in, (size_t)640*480*sizeof(float));
extern cv::VideoCapture camera;
cv::Mat mIn;
camera >> mIn;
printf("width: %d; height: %d;\n", mIn.cols, mIn.rows);
cvtColor(mIn, mIn, CV_BGR2GRAY);
// convert to float representation (opencv loads image values as single bytes by default)
mIn.convertTo(mIn, CV_32F);
// convert range of each channel to [0,1] (opencv default is [0,255])
mIn /= 255.f;
cudaMemcpy(d_in, mIn.data, (size_t)640*480*sizeof(float), cudaMemcpyHostToDevice);
// Execute kernel
executeKernel(d_in, positions, 640, 480, float(time(0) - start) * 0.1);
cudaFree(d_in);
// Unmap buffer object
cudaGraphicsUnmapResources(1, &positionsVBO_CUDA, 0);
// Render from buffer object
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//func.glBindBuffer(GL_ARRAY_BUFFER, positionsVBO); // what is it?
glDrawPixels( 640, 480, GL_RGBA, GL_UNSIGNED_BYTE, 0 ); // TODO
}
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget>
#include <QGLFunctions>
class GlWidget : public QGLWidget
{
Q_OBJECT
public:
explicit GlWidget(QWidget *parent = 0);
~GlWidget();
QSize sizeHint() const;
protected:
void initializeGL();
void paintGL();
private:
QGLFunctions func;
time_t start;
};
#endif // GLWIDGET_H
QT += core gui opengl
CONFIG += debug
TARGET = hello-opengl
TEMPLATE = app
SOURCES += main.cpp glwidget.cpp
HEADERS += glwidget.h kernel.h
CUDA_SOURCES += kernel.cu
LIBS += -lGLEW -lcudart -lcuda -lopencv_core -lopencv_highgui -lopencv_imgproc
QMAKE_LFLAGS += -Wl,-rpath,/usr/lib/nvidia-331-updates -Wl,-rpath,/usr/lib/nvidia-331-updates/tls
# Path to cuda toolkit install
CUDA_DIR = /usr
# Path to header and libs files
INCLUDEPATH += $$CUDA_DIR/include
QMAKE_LIBDIR += $$CUDA_DIR/lib64
QMAKE_LIBDIR += /usr/lib/nvidia-331-updates /usr/lib/nvidia-331-updates/tls
# GPU architecture
CUDA_ARCH = sm_10
NVCCFLAGS = --compiler-options -use_fast_math --ptxas-options=-v
CUDA_INC = $$join(INCLUDEPATH,' -I','-I',' ')
cuda.commands = $$CUDA_DIR/bin/nvcc -m64 -O3 -arch=$$CUDA_ARCH -c $$NVCCFLAGS $$CUDA_INC $$LIBS ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_OUT}
cuda.dependency_type = TYPE_C
cuda.depend_command = $$CUDA_DIR/bin/nvcc -O3 -M $$CUDA_INC $$NVCCFLAGS ${QMAKE_FILE_NAME}
cuda.input = CUDA_SOURCES
cuda.output = ${OBJECTS_DIR}${QMAKE_FILE_BASE}_cuda.o
# Tell Qt that we want add more stuff to the Makefile
QMAKE_EXTRA_COMPILERS += cuda
#include "kernel.h"
__global__ void createVertices(float *in, uchar4* positions, int width, int height)
{
unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
unsigned char intensity = roundf(255 * in[y * width + x]);
// Write positions
positions[y * width + x].x = intensity;
positions[y * width + x].y = intensity;
positions[y * width + x].z = intensity;
positions[y * width + x].w = 255;
}
void executeKernel(float *d_in, void *positions_, int width, int height, float time)
{
uchar4 *positions = (uchar4 *)positions_;
dim3 dimBlock(16, 16, 1);
dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);
createVertices<<<dimGrid, dimBlock>>>(d_in, positions, width, height);
}
#ifndef _KERNEL_H
#define _KERNEL_H
extern "C" void executeKernel(float *d_in, void *positions_, int width, int height, float time);
#endif // _KERNEL_H
#include <iostream>
#include <QApplication>
#include <opencv2/highgui/highgui.hpp>
#include "glwidget.h"
cv::VideoCapture camera;
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// Init camera
camera.open(0);
if(!camera.isOpened()) {
std::cerr << "ERROR: Could not open camera" << std::endl;
return 1;
}
int camW = 640;
int camH = 480;
camera.set(CV_CAP_PROP_FRAME_WIDTH,camW);
camera.set(CV_CAP_PROP_FRAME_HEIGHT,camH);
GlWidget w;
w.show();
return app.exec();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment