Skip to content

Instantly share code, notes, and snippets.

@ohga
Created October 16, 2017 04:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ohga/92189a843fbcbe1ffabdbc1043fbe165 to your computer and use it in GitHub Desktop.
Save ohga/92189a843fbcbe1ffabdbc1043fbe165 to your computer and use it in GitHub Desktop.
// ** きたないコード **
// 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