Created
October 16, 2017 04:28
-
-
Save ohga/92189a843fbcbe1ffabdbc1043fbe165 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ** きたないコード ** | |
// video(0) とか IPカメラとか mjpeg とか、opencv のvideo入力ソースから読んで、fb にマンガカメラ風の映像を垂れ流すやつ。 | |
// ついでなので、日時とか biff とかを書いていた。 | |
// Cortex-A8 800MHzに LCD-8000U を繋いで動作。 | |
// g++ gomi.cc -o cam `pkg-config --cflags opencv` `pkg-config --libs opencv` | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <sys/mman.h> | |
#include <linux/fb.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <sys/ioctl.h> | |
#include <sys/stat.h> | |
#include <signal.h> | |
#include <opencv2/highgui/highgui.hpp> | |
#include <opencv2/opencv.hpp> | |
void before(void) __attribute__((constructor)); | |
void after(void) __attribute__((destructor)); | |
using namespace cv; | |
using namespace std; | |
static struct fb_var_screeninfo screen_info; | |
static struct fb_fix_screeninfo fixed_info; | |
static int fd = -1; | |
static char *buffer = NULL; | |
static size_t buflen = -1; | |
static int loop = 0; | |
void sig(int sig) | |
{ | |
fprintf(stdout, "sig catch:%d\n", sig); | |
loop = 0; | |
return; | |
} | |
int file_exists (char * fileName) | |
{ | |
struct stat buf; | |
return (stat(fileName, &buf) == 0); | |
} | |
int main(void) | |
{ | |
//Size cap_size(432, 240); | |
Size cap_size(640, 360); | |
Mat img, src, scr; | |
int ii, sx, sy, depth, num_w = 32; | |
// float zoom_factor = 1.44; | |
float zoom_factor = 1.0; | |
time_t start, nn, old_nn = 0, old_sch = 0; | |
struct tm *tm; | |
Mat num[12], bar, sch; | |
struct stat st; | |
VideoCapture video(0); | |
//VideoCapture video("rtsp://10.0.0.2/stream1"); | |
//VideoCapture video("http://192.168.0.222:8090/live.mjpg"); | |
if (!video.isOpened()) { | |
fprintf(stderr, "err.\n"); | |
return 1; | |
} | |
video >> scr; | |
video.set(CV_CAP_PROP_FRAME_WIDTH, cap_size.width); | |
video.set(CV_CAP_PROP_FRAME_HEIGHT, cap_size.height); | |
sx = (screen_info.xres - (cap_size.width * zoom_factor)) / 2 + screen_info.xoffset; | |
sy = (screen_info.yres - (cap_size.height * zoom_factor)) / 2 + screen_info.yoffset + 48; | |
depth = (screen_info.bits_per_pixel / 8); | |
scr = imread("back.png", CV_LOAD_IMAGE_GRAYSCALE); | |
sch.data = NULL; | |
for (ii = 0; ii < 12; ii++) { | |
char gomi[32]; | |
Mat tmp, tmp2; | |
snprintf(gomi, sizeof(gomi), "num/%d.png", ii); | |
tmp = imread(gomi, CV_LOAD_IMAGE_COLOR); | |
num[ii] = tmp.clone(); | |
} | |
int rr = 0; | |
time(&start); | |
while (loop) { | |
Mat edge, work, work2; | |
if (zoom_factor == 1.0) { | |
video >> src; | |
if (src.empty()) | |
break; | |
} else { | |
video >> img; | |
if (img.empty()) | |
break; | |
resize(img, src, Size(), zoom_factor, zoom_factor, CV_INTER_NN); | |
} | |
cvtColor(src, src, COLOR_BGR2GRAY); | |
flip(src, src, 1); | |
src.copyTo(work); | |
Canny(src, edge, 50, 200); | |
time(&nn); | |
if (nn != old_nn) { | |
int pos = 0; | |
char text[64]; | |
bar = Mat::zeros(Size(32 * 19, 42), CV_8UC3); | |
tm = localtime(&nn); | |
snprintf(text, sizeof(text), "%d/%02d/%02d %02d:%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, | |
tm->tm_hour, tm->tm_min, tm->tm_sec); | |
for (ii = 0, pos = 0; ii < (int)strlen(text); ii++) { | |
cv::Mat canvas(bar, Rect(pos, 10, num_w, num_w)); | |
switch (text[ii]) { | |
case '0': | |
case '1': | |
case '2': | |
case '3': | |
case '4': | |
case '5': | |
case '6': | |
case '7': | |
case '8': | |
case '9': | |
num[text[ii] - 48].copyTo(canvas); | |
break; | |
case '/': | |
num[10].copyTo(canvas); | |
break; | |
case ':': | |
num[11].copyTo(canvas); | |
break; | |
default: | |
break; | |
} | |
pos += num_w; | |
} | |
cvtColor(bar, bar, CV_RGBA2BGR); | |
flip(bar, bar, 1); | |
old_nn = nn; | |
} | |
if (stat("/tmp/text.txt", &st) != 0 && stat("/tmp/out.png", &st) == 0) { | |
if (old_sch != st.st_mtime) { | |
sch = imread("/tmp/out.png"); | |
if (sch.data) { | |
cvtColor(sch, sch, CV_RGBA2BGR); | |
flip(sch, sch, 1); | |
} | |
} | |
old_sch = st.st_mtime; | |
} else if (stat("/root/chroot/tmp/text.txt", &st) != 0 && stat("/root/chroot/tmp/sch.png", &st) == 0) { | |
if (old_sch != st.st_mtime) { | |
sch = imread("/root/chroot/tmp/out.png"); | |
if (sch.data) { | |
cvtColor(sch, sch, CV_RGBA2BGR); | |
flip(sch, sch, 1); | |
} | |
} | |
old_sch = st.st_mtime; | |
} | |
Vec3b *ptr = bar.ptr<Vec3b>(0); | |
Vec3b *sch_ptr = NULL; | |
if (sch.data) | |
sch_ptr = sch.ptr<Vec3b>(0); | |
for (int yy = 0; yy < work.rows; yy++) { | |
int tmp_y = (yy + sy) * fixed_info.line_length; | |
for (int xx = 0; xx < bar.cols; xx++) { | |
int rr, gg, bb, location = ((work.cols - xx) + sx) * depth + tmp_y; | |
Vec3b edge_vec = edge.at<Vec3b>(yy, xx / 3); | |
uchar dd = (uchar)edge_vec[0]; | |
if (dd > 128) { | |
rr = gg = bb = 1; | |
} else { | |
Vec3b work_vec = work.at<Vec3b>(yy, xx / 3); | |
uchar cc = (uchar)work_vec[0]; | |
if (cc < 30) { | |
rr = gg = bb = 32; | |
} else if (30 <= cc && cc < 70) { | |
rr = gg = bb = 64; | |
} else if (70 <= cc && cc < 110) { | |
rr = gg = bb = scr.at<Vec3b>(yy, xx / 3)[0]; | |
} else { | |
rr = gg = bb = 255; | |
} | |
} | |
if (yy < bar.rows) { | |
unsigned short int cc = ((*(ptr))[0] >> 3) << 11 | ((*(ptr))[1] >> 2) << 5 | ((*(ptr))[2] >> 3); | |
if (cc != 0 && cc != 65535){ | |
*((unsigned short int *)(buffer + location)) = cc; | |
} else { | |
*((unsigned short int *)(buffer + location)) = (rr >> 3) << 11 | (gg >> 2) << 5 | (bb >> 3); | |
} | |
ptr++; | |
} else if (sch_ptr != NULL) { | |
unsigned short int cc = | |
((*(sch_ptr))[0] >> 3) << 11 | ((*(sch_ptr))[1] >> 2) << 5 | ((*(sch_ptr))[2] >> 3); | |
if (cc != 0 && cc != 65535) { | |
*((unsigned short int *)(buffer + location)) = cc; | |
} else { | |
*((unsigned short int *)(buffer + location)) = (rr >> 3) << 11 | (gg >> 2) << 5 | (bb >> 3); | |
} | |
sch_ptr++; | |
} else { | |
*((unsigned short int *)(buffer + location)) = (rr >> 3) << 11 | (gg >> 2) << 5 | (bb >> 3); | |
} | |
} | |
} | |
} | |
return 0; | |
} | |
void before(void) | |
{ | |
signal(SIGINT, sig); | |
signal(SIGTERM, sig); | |
signal(SIGPIPE, sig); | |
signal(SIGHUP, sig); | |
signal(SIGSTOP, sig); | |
signal(SIGQUIT, sig); | |
signal(SIGCHLD, sig); | |
fd = open("/dev/fb0", O_RDWR); | |
if (fd < 0) { | |
fd = open("/dev/fb1", O_RDWR); | |
if (fd < 0) { | |
perror("open"); | |
return; | |
} | |
} | |
if (ioctl(fd, FBIOGET_VSCREENINFO, &screen_info) || ioctl(fd, FBIOGET_FSCREENINFO, &fixed_info)) { | |
perror("ioctl"); | |
close(fd); | |
return; | |
} | |
buflen = screen_info.yres_virtual * fixed_info.line_length; | |
buffer = (char *)mmap(NULL, buflen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | |
loop = 1; | |
// alarm(900); | |
} | |
void after(void) | |
{ | |
if (buffer && buffer != MAP_FAILED) { | |
munmap(buffer, buflen); | |
fprintf(stdout, "unmap.\n"); | |
} | |
if (fd != -1) { | |
close(fd); | |
fprintf(stdout, "close.\n"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment