rev |
line source |
eleni@5
|
1 #include <GL/gl.h>
|
eleni@4
|
2 #include <cxcore.h>
|
eleni@9
|
3 #include <opencv2/imgproc/imgproc.hpp>
|
eleni@10
|
4 #include <opencv2/photo/photo.hpp>
|
eleni@9
|
5
|
eleni@4
|
6 #include <highgui.h> //TODO remove
|
eleni@6
|
7 #include <cv.h> //TODO remove
|
eleni@4
|
8
|
eleni@2
|
9 #include <pthread.h>
|
eleni@1
|
10 #include <stdio.h>
|
eleni@2
|
11 #include <string.h>
|
eleni@1
|
12
|
eleni@1
|
13 #include "frame.h"
|
eleni@2
|
14 #include "kinect.h"
|
eleni@1
|
15
|
eleni@2
|
16 extern Frame *frame;
|
eleni@2
|
17 extern KinectParams *kin_params;
|
eleni@1
|
18
|
eleni@2
|
19 extern bool has_video;
|
eleni@2
|
20 extern bool has_depth;
|
eleni@2
|
21
|
eleni@2
|
22 Frame::Frame()
|
eleni@1
|
23 {
|
eleni@5
|
24 video_buf = cv::Mat::zeros(KINECT_VIDEO_HEIGHT, KINECT_VIDEO_WIDTH, CV_8UC3);
|
eleni@9
|
25 depth_buf = cv::Mat::zeros(KINECT_DEPTH_HEIGHT, KINECT_DEPTH_WIDTH, CV_8UC1);
|
eleni@5
|
26
|
eleni@5
|
27 tex_setup();
|
eleni@5
|
28 }
|
eleni@5
|
29
|
eleni@5
|
30 void Frame::tex_setup()
|
eleni@5
|
31 {
|
eleni@5
|
32 glGenTextures(1, &video_tex);
|
eleni@5
|
33 glGenTextures(1, &depth_tex);
|
eleni@5
|
34
|
eleni@5
|
35 glBindTexture(GL_TEXTURE_2D, video_tex);
|
eleni@5
|
36 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
eleni@5
|
37 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
eleni@5
|
38 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
eleni@5
|
39 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
eleni@12
|
40 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, KINECT_VIDEO_WIDTH, KINECT_VIDEO_HEIGHT,
|
eleni@12
|
41 0, GL_BGR, GL_UNSIGNED_BYTE, 0);
|
eleni@5
|
42
|
eleni@5
|
43 glBindTexture(GL_TEXTURE_2D, depth_tex);
|
eleni@5
|
44 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
eleni@5
|
45 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
eleni@5
|
46 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
eleni@5
|
47 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
eleni@12
|
48 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, KINECT_DEPTH_WIDTH, KINECT_DEPTH_HEIGHT,
|
eleni@12
|
49 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
|
eleni@1
|
50 }
|
eleni@1
|
51
|
eleni@2
|
52 void Frame::process()
|
eleni@1
|
53 {
|
eleni@12
|
54 if(has_video) {
|
eleni@12
|
55 glBindTexture(GL_TEXTURE_2D, video_tex);
|
eleni@12
|
56 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, KINECT_VIDEO_WIDTH, KINECT_VIDEO_HEIGHT, GL_BGR, GL_UNSIGNED_BYTE, video_buf.data);
|
eleni@13
|
57 }
|
eleni@13
|
58 if(has_depth) {
|
eleni@13
|
59 glBindTexture(GL_TEXTURE_2D, depth_tex);
|
eleni@13
|
60 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, KINECT_DEPTH_WIDTH, KINECT_DEPTH_HEIGHT, GL_LUMINANCE, GL_UNSIGNED_BYTE, depth_buf.data);
|
eleni@12
|
61 }
|
eleni@12
|
62 if(has_video && has_depth) {//pot
|
eleni@12
|
63 }
|
eleni@2
|
64 }
|
eleni@2
|
65
|
eleni@2
|
66 void video_cb(freenect_device *kin_dev, void *video, uint32_t time)
|
eleni@2
|
67 {
|
eleni@4
|
68 if(!video || !frame) {
|
eleni@2
|
69 has_video = false;
|
eleni@2
|
70 return;
|
eleni@2
|
71 }
|
eleni@2
|
72
|
eleni@5
|
73 /* freenect video data to cv mat: */
|
eleni@5
|
74 unsigned char* src = (unsigned char*)video;
|
eleni@5
|
75 unsigned char* dest = frame->video_buf.data;
|
eleni@5
|
76
|
eleni@5
|
77 for(int i=0; i<KINECT_VIDEO_HEIGHT * KINECT_VIDEO_WIDTH; i++) {
|
eleni@5
|
78 dest[0] = src[2];
|
eleni@5
|
79 dest[1] = src[1];
|
eleni@5
|
80 dest[2] = src[0];
|
eleni@5
|
81 dest += 3;
|
eleni@5
|
82 src += 3;
|
eleni@5
|
83 }
|
eleni@2
|
84 has_video = true;
|
eleni@1
|
85 }
|
eleni@1
|
86
|
eleni@1
|
87 void depth_cb(freenect_device *kin_dev, void *depth, uint32_t time)
|
eleni@1
|
88 {
|
eleni@5
|
89 if(!depth || !frame) {
|
eleni@2
|
90 has_depth = false;
|
eleni@2
|
91 return;
|
eleni@2
|
92 }
|
eleni@2
|
93
|
eleni@5
|
94 /* freenect depth data to cv mat: */
|
eleni@8
|
95 uint16_t* src = (uint16_t*)depth;
|
eleni@9
|
96 uint8_t* dest = (uint8_t*)frame->depth_buf.data;
|
eleni@5
|
97
|
eleni@8
|
98 for(int i=0; i<KINECT_DEPTH_HEIGHT * KINECT_DEPTH_WIDTH; i++) {
|
eleni@8
|
99 uint16_t val = *src;
|
eleni@8
|
100 if(val >= 2047) {
|
eleni@11
|
101 val = 2047;
|
eleni@8
|
102 }
|
eleni@9
|
103 *dest = val >> 3;
|
eleni@8
|
104 src++;
|
eleni@8
|
105 dest++;
|
eleni@8
|
106 }
|
eleni@5
|
107
|
eleni@11
|
108 // cv::GaussianBlur(frame->depth_buf, frame->depth_buf, cv::Size(3, 3), 0.5);
|
eleni@10
|
109
|
eleni@11
|
110 /*
|
eleni@11
|
111 //Inpaint to fill the regions
|
eleni@11
|
112 //^ val = 0 instead of 2047 and:
|
eleni@10
|
113 cv::Mat mask = 255 - frame->depth_buf;
|
eleni@10
|
114 cv::threshold(mask, mask, 254, 255, 3);
|
eleni@10
|
115 cv::inpaint(frame->depth_buf, mask, frame->depth_buf, 1, cv::INPAINT_NS);
|
eleni@11
|
116 */
|
eleni@2
|
117 has_depth = true;
|
eleni@1
|
118 }
|
eleni@5
|
119
|
eleni@5
|
120 bool save_video_ppm(void *video, int w, int h)
|
eleni@5
|
121 {
|
eleni@5
|
122 FILE *fp;
|
eleni@5
|
123 if(!(fp = fopen("test_video.ppm", "wb"))) {
|
eleni@5
|
124 fprintf(stderr, "Failed to open video file for writing.\n");
|
eleni@5
|
125 return false;
|
eleni@5
|
126 }
|
eleni@6
|
127 fprintf(fp, "P6\n%d %d\n255\n", w, h);
|
eleni@6
|
128 unsigned char *ptr = (unsigned char*)video;
|
eleni@5
|
129 for(int i=0; i<w * h * 3; i++) {
|
eleni@5
|
130 fputc(*ptr, fp);
|
eleni@5
|
131 ptr++;
|
eleni@5
|
132 }
|
eleni@5
|
133 fclose(fp);
|
eleni@5
|
134 return true;
|
eleni@5
|
135 }
|