用openvc 统制鼠标 来移动和打开文件

用openvc 控制鼠标 来移动和打开文件

这一阵做了冷板凳。蛋有淡淡的忧伤。开始吓唬闹ing....................

 

需求:

有时候坐在离鼠标比较远的地方(比如推到沙发上)看网页,看电影要用鼠标去控制,还得蹭过去。写个用握拳挥动来控制鼠标移动,用掌来打开文件的程序。

打算到时候可以移到自家android电视上去。

 

困难:

之前也没有写过c 语言程序(还读书的时候考级用过),开始看opencv 更是雾水,还好 “凡是不决问狗狗”。顺便蛋伤下:狗狗提供的不只是口粮,还有思想。 

 

 

下面是代码  ,另外,我想写一个基于图片中实物分类的程序,作用是可以从网上自动down 图片,然后按照要的分类 比如 鲜花 或者 狗狗  来自动保存和分类。  爬虫  存储 ,分类和展示 用 jsoup  ,mongo gridfs,  spring mvc  和 js 已完成。准备训练大量的不同事务的分级文件。有兴趣多交流。

 

下面是代码    

大概步骤

1、抓视频,帧  处理

2、看有没有 手掌 (双击) 和拳头移动(鼠标移动),有的化就处理。

 

 

 

#include "opencv2/objdetect/objdetect.hpp"

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/imgproc/imgproc.hpp"

#include <string.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <linux/input.h>

#include <linux/uinput.h>

#include <stdio.h>

#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

#include <iostream>

#include <stdlib.h>

#include <pthread.h>

 

using namespace std;

using namespace cv;

 

 

void mousemove(int fd, int x, int y);

void mousedoubleclick(int fd);

 

void fist(Mat frame);

void palm(Mat frame);

 

void *thread1(void *);

 

struct mypoint {

int x1;

int y1;

 

};

 

mypoint p;

 

int fd_mouse;

 

//  这两个链接分类的文件我是从 qq 手势 里扣出来的,正准备自己训练几个不同手势的文件

String palmfile = "data/mycascade/palm.dat";

String fistfile = "data/mycascade/fist.dat";

 

int xarray = 0;

int yarray = 0;

 

int movex = 0;

int movey = 0;

 

int palmcount = 0;

int fistcount = 0;

 

bool waitfist = false;

bool waitpalm = false;

 

bool isfirst = true;

 

pthread_t pid1;

 

float lv = 1;

 

CascadeClassifier palm_cascade;

CascadeClassifier fist_cascade;

 

//string window_name = "Capture - Face detection";

 

int objectDetectionxx(int argc, char** argv)

 

{

 

CvCapture* capture;

Mat frame;

 

 

 

if (!palm_cascade.load(palmfile)) {

printf("--(!)Error loading\n");

return -1;

};

if (!fist_cascade.load(fistfile)) {

printf("--(!)Error loading\n");

return -1;

};

 

 

    //打开鼠标文件  不同机器可能不一样 我的

fd_mouse = open("/dev/input/event3", O_RDWR);

 

if (fd_mouse <= 0) {

printf("error open mouse/n  please chmod +wr /dev/input/e*");

 

}

 

capture = cvCaptureFromCAM(-1);

Mat frame_gray;

 

if (capture) {

 

while (true) {

 

frame = cvQueryFrame(capture);

if (!frame.empty()) {

 

cvtColor(frame, frame_gray, CV_BGR2GRAY);

 

equalizeHist(frame_gray, frame_gray);

 

 

                //再 双击有有各线程设置waitfist这个值, 这个线程主要是睡  防止双击频繁

if (!waitfist) {

 

palm(frame_gray);

}

 

if (!waitpalm) {

fist(frame_gray);

 

}

 

// imshow(window_name, frame_gray);

 

} else {

printf(" --(!) No captured frame -- Break!");

break;

}

 

waitKey(10);

// int c = waitKey(50);

// if ((char) c == 'c') {

// break;

// }

}

}

return 0;

}

 

 

 

//测试视频中是否有 手掌出现, 手掌一出现 鼠标停止移动,双击

void palm(Mat frame) {

 

std::vector<Rect> palmrect;

 

palm_cascade.detectMultiScale(frame, palmrect, 1.1, 2,

0 | CV_HAAR_SCALE_IMAGE, Size(70, 70));

 

if (palmrect.size() > 0) {

 

fistcount++;

 

if (fistcount == 3) {

 

if (pthread_create(&pid1, NULL, thread1, NULL) != 0) {

printf("create thread1 failed/n");

}

 

mousedoubleclick(fd_mouse);

 

}

 

} else {

 

fistcount = 0;

}

 

}

 

//检测是否有拳头出现  出想的坐标

void fist(Mat frame) {

 

 

 

std::vector<Rect> fistrect;

 

//-- Detect faces

fist_cascade.detectMultiScale(frame, fistrect, 1.1, 2,

0 | CV_HAAR_SCALE_IMAGE, Size(80, 80));

 

if (fistrect.size() > 0) {

 

palmcount = 0;

 

p.x1 = fistrect[0].x + fistrect[0].width * 0.5;

p.y1 = fistrect[0].y + fistrect[0].width * 0.5;

 

// Point center(fistrect[0].x + fistrect[0].width * 0.5,

// fistrect[0].y + fistrect[0].height * 0.5);

// ellipse(frame, center,

// Size(fistrect[0].width * 0.5, fistrect[0].height * 0.5), 0, 0,

// 360, Scalar(255, 0, 0), 2, 8, 0);

 

if ((xarray - p.x1) * (xarray - p.x1) > 25

&& (p.y1 - yarray) * (p.y1 - yarray) > 25) {

 

if (xarray != 0) {

 

mousemove(fd_mouse, lv * (xarray - p.x1), lv * (p.y1 - yarray));

 

cout << "palm:" << "movex:=" << lv * (xarray - p.x1) << "nx:="

<< p.x1 << "ox:=" << xarray << endl;

cout << "palm:" << "movey:=" << lv * (p.y1 - yarray) << "ny:="

<< p.y1 << "oy:=" << yarray << endl;

xarray = p.x1;

yarray = p.y1;

} else {

xarray = p.x1;

yarray = p.y1;

}

}

 

} else {

 

palmcount++;

 

if (palmcount > 5) {

palmcount = 0;

xarray = 0;

yarray = 0;

}

}

 

}

 

 

//鼠标移动

void mousemove(int fd, int x, int y) {

struct input_event event;

 

memset(&event, 0, sizeof(event));

gettimeofday(&event.time, NULL);

event.type = EV_REL;

event.code = REL_X;

event.value = x;

write(fd, &event, sizeof(event));

 

event.type = EV_REL;

event.code = REL_Y;

event.value = y;

write(fd, &event, sizeof(event));

 

event.type = EV_SYN;

event.code = SYN_REPORT;

event.value = 0;

write(fd, &event, sizeof(event));

 

}

 

 

//鼠标左键双击

void mousedoubleclick(int fd) {

struct input_event event;

memset(&event, 0, sizeof(event));

gettimeofday(&event.time, NULL);

 

event.type = EV_KEY;

event.code = BTN_LEFT;

event.value = 1;

write(fd, &event, sizeof(event));

 

event.type = EV_KEY;

event.code = BTN_LEFT;

event.value = 0;

write(fd, &event, sizeof(event));

 

event.type = EV_KEY;

event.code = BTN_LEFT;

event.value = 1;

write(fd, &event, sizeof(event));

 

event.type = EV_KEY;

event.code = BTN_LEFT;

event.value = 0;

write(fd, &event, sizeof(event));

 

event.type = EV_SYN;

event.code = SYN_REPORT;

event.value = 0;

write(fd, &event, sizeof(event));

 

}

 

 

//当鼠标双击后会触发这个线程 ,这个线程的左右是 防止重复的双击

void *thread1(void *) {

 

cout << "fist:" << "waitfist begin!  double click" << endl;

waitfist = true;

waitpalm = true;

usleep(100 * 1000);

waitpalm = false;

usleep(200 * 1000);

 

cout << "fist:waitfist end!" << endl;

waitfist = false;

 

}