Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include "hidapi.h"
- #include "opencv2/core/core.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include <algorithm>
- #include <fstream>
- #include <iostream>
- #include <stdio.h>
- #include <stdlib.h>
- #include <windows.h>
- using namespace cv;
- using namespace std;
- void drawRect(cv::Mat &background, int sx, int sy, int width, int height, int col_r, int col_g, int col_b);
- void obtainTargets(const cv::Mat &background, const std::vector<cv::Mat> &hostiles, const std::vector<cv::Mat> &hostiles_2, std::vector<std::vector<float > > &hmatch);
- void overlayImage(const cv::Mat &background, const cv::Mat &foreground, cv::Mat &output, cv::Point2i location);
- int main(int argc, char* argv[]) {
- // HID API Initialization
- int res;
- unsigned char buf[65];
- #define MAX_STR 255
- wchar_t wstr[MAX_STR];
- hid_device *handle;
- int i;
- // Enumerate and print the HID devices on the system
- bool found_launcher=false;
- unsigned short launcher_vid, launcher_pid;
- struct hid_device_info *devs, *cur_dev;
- devs = hid_enumerate(0x0, 0x0);
- cur_dev = devs;
- while (cur_dev) {
- char cdps_c[21];
- wcstombs(cdps_c,cur_dev->product_string,20); cdps_c[20] = '\0'; std::string cdps(cdps_c);
- if (cdps.compare("USB Missile Launcher")==0) {
- std::cout << "Opening ML" << std::endl;
- launcher_vid=cur_dev->vendor_id;
- launcher_pid=cur_dev->product_id;
- found_launcher=true;
- } else {
- std::cout << "Name: " << cdps << std::endl;
- }
- printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls",
- cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
- printf("\n");
- printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string);
- printf(" Product: %ls\n", cur_dev->product_string);
- printf("\n");
- cur_dev = cur_dev->next;
- }
- hid_free_enumeration(devs);
- // Connect to missile launcher
- if (found_launcher) {
- handle = hid_open(launcher_vid, launcher_pid, NULL);
- std::cout << "handle: " << handle << std::endl;
- } else {
- std::cout << "Cannot connect to launcher." << endl;
- exit(0);
- }
- VideoCapture cap(0); // open the video camera no. 0
- if (!cap.isOpened()) {
- std::cout << "Cannot open the video cam." << endl;
- exit(0);
- }
- double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
- double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
- std::cout << "Frame size : " << dWidth << " x " << dHeight << endl;
- // Load hostile targets
- std::vector<Mat> h; h.resize(6);
- h[0] = imread("h0.png", CV_LOAD_IMAGE_GRAYSCALE);
- h[1] = imread("h1.png", CV_LOAD_IMAGE_GRAYSCALE);
- h[2] = imread("h2.png", CV_LOAD_IMAGE_GRAYSCALE);
- h[3] = imread("h3.png", CV_LOAD_IMAGE_GRAYSCALE);
- h[4] = imread("h4.png", CV_LOAD_IMAGE_GRAYSCALE);
- h[5] = imread("h5.png", CV_LOAD_IMAGE_GRAYSCALE);
- std::vector<Mat> h2; h2.resize(6);
- resize(h[0], h2[0], Size(7,7), 0, 0, INTER_CUBIC);
- resize(h[1], h2[1], Size(7,7), 0, 0, INTER_CUBIC);
- resize(h[2], h2[2], Size(7,7), 0, 0, INTER_CUBIC);
- resize(h[3], h2[3], Size(7,7), 0, 0, INTER_CUBIC);
- resize(h[4], h2[4], Size(7,7), 0, 0, INTER_CUBIC);
- resize(h[5], h2[5], Size(7,7), 0, 0, INTER_CUBIC);
- // Load videocam overlay
- cout << "Loading overlay..." << endl;
- Mat overlay = imread("overlay.png",-1);
- resize(overlay, overlay, Size(640, 480), 0, 0, INTER_CUBIC);
- namedWindow("Buk-S Automated Firing Solution",CV_WINDOW_AUTOSIZE);
- //namedWindow("MyVideo",CV_WINDOW_NORMAL);
- //setWindowProperty("MyVideo", CV_WND_PROP_FULLSCREEN, 1.0);
- // Add a wait to allow webcam to initialize reliably
- unsigned int last_call_time=timeGetTime(); unsigned int now_time=timeGetTime(); while (now_time-last_call_time<2000) { now_time=timeGetTime(); }
- unsigned int last_cmd_time=timeGetTime();
- unsigned int last_fire_time=timeGetTime()-5000;
- bool frame_written=false;
- while (1) {
- Mat frame, gframe, oframe;
- bool bSuccess = cap.read(frame); // read a new frame from video
- cv::Size s = frame.size();
- // N.B. don't break, first frame tends to fail
- if (!bSuccess) {
- std::cout << "Cannot read a frame from video stream" << endl;
- //break;
- } else if (!frame_written && s.width>0 && s.height>0) {
- frame_written=true;
- imwrite("frame.jpg", frame);
- }
- if (s.width>0 && s.height>0) {
- // Detect targets
- cvtColor(frame,gframe,CV_BGR2GRAY);
- std::vector<std::vector<float > > hm; hm.resize(6); for (int i=0;i<6;i++) { hm[i].resize(3); for (int j=0;j<2;j++) { hm[i][j]=-9999.0f; } hm[i][2]=999.0f; }
- resize(gframe, gframe, Size(320, 240), 0, 0, INTER_CUBIC);
- obtainTargets(gframe,h,h2,hm);
- int active_target=0;
- for (int t=1;t<=5;t++) {
- if (hm[t][2]<3.0f && hm[t][0]>=0.0f && hm[t][1]>=0.0f) {
- drawRect(frame,hm[t][0]*2-8,hm[t][1]*2-8,42,42,0,255,0);
- active_target=t;
- break;
- }
- }
- overlayImage(frame, overlay, oframe, cv::Point(0,0));
- resize(oframe, oframe, Size(640, 480), 0, 0, INTER_CUBIC);
- imshow("Buk-S Automated Firing Solution", oframe);
- // Move towards target
- if (active_target>0 && timeGetTime()-last_cmd_time>500 && timeGetTime()-last_fire_time>5000) {
- if (hm[active_target][2]<3.0f) {
- int hx=hm[active_target][0]*2; int hy=hm[active_target][1]*2;
- std::cout << "hx: " << hx << " hy: " << hy << " ";
- // Horizontal
- if (hx<320-20) {
- unsigned char cbuf[17];
- cbuf[0]=0x00; cbuf[1]=0x02; cbuf[2]=0x04; for (int j=3;j<=16;j++) { cbuf[j]=0x00; }
- int retval=0;
- retval=hid_write(handle,cbuf,65);
- std::cout << timeGetTime() << ": LEFT " << retval << std::endl;
- } else if (hx>320-20) {
- unsigned char cbuf[17];
- cbuf[0]=0x00; cbuf[1]=0x02; cbuf[2]=0x08; for (int j=3;j<=16;j++) { cbuf[j]=0x00; }
- int retval=0;
- retval=hid_write(handle,cbuf,65);
- std::cout << timeGetTime() << ": RIGHT " << retval << std::endl;
- } else if (hy<240-20) { // Vertical
- unsigned char cbuf[17];
- cbuf[0]=0x00; cbuf[1]=0x02; cbuf[2]=0x02; for (int j=3;j<=16;j++) { cbuf[j]=0x00; }
- int retval=0;
- retval=hid_write(handle,cbuf,65);
- std::cout << timeGetTime() << ": UP " << retval << std::endl;
- } else if (hy>240-20) {
- unsigned char cbuf[17];
- cbuf[0]=0x00; cbuf[1]=0x02; cbuf[2]=0x01; for (int j=3;j<=16;j++) { cbuf[j]=0x00; }
- int retval=0;
- retval=hid_write(handle,cbuf,65);
- std::cout << timeGetTime() << ": DOWN " << retval << std::endl;
- }
- // Fire
- if (timeGetTime()-last_fire_time>5000 && hx>=320-20 && hx<=320+20 && hy>=240-20 && hy<=240-20) {
- unsigned char cbuf[17];
- // Stop first!
- cbuf[0]=0x00; cbuf[1]=0x02; for (int j=2;j<=16;j++) { cbuf[j]=0x00; }
- int retval=hid_write(handle,cbuf,65);
- std::cout << timeGetTime() << ": FIRESTOP " << retval << std::endl;
- cbuf[0]=0x00; cbuf[1]=0x02; cbuf[2]=0x10; for (int j=3;j<=16;j++) { cbuf[j]=0x00; }
- retval=hid_write(handle,cbuf,65);
- std::cout << timeGetTime() << ": FIRE " << retval << std::endl;
- last_fire_time=timeGetTime();
- }
- // Sleep and stop, to limit movement
- if (timeGetTime()-last_fire_time>5000) {
- Sleep(20);
- unsigned char cbuf[17];
- cbuf[0]=0x00; cbuf[1]=0x02; for (int j=2;j<=16;j++) { cbuf[j]=0x00; }
- int retval=hid_write(handle,cbuf,65);
- std::cout << timeGetTime() << ": STOP " << retval << std::endl;
- }
- }
- last_cmd_time=timeGetTime();
- }
- }
- if (waitKey(30) == 27) {
- std::cout << "Exiting..." << endl;
- unsigned char cbuf[17];
- cbuf[0]=0x00; cbuf[1]=0x02; for (int j=2;j<=16;j++) { cbuf[j]=0x00; }
- int retval=hid_write(handle,cbuf,65);
- std::cout << timeGetTime() << ": EXITSTOP " << retval << std::endl;
- break;
- }
- }
- return 0;
- }
- void drawRect(cv::Mat &background, int sx, int sy, int width, int height, int col_r, int col_g, int col_b) {
- Vec3b color; color[0]=col_r; color[1]=col_g; color[2]=col_b;
- for (int x=sx; x<sx+width; ++x) {
- if (x>0 && x<background.cols-1) {
- if (sy>0 && sy<background.rows-1) background.at<Vec3b>(Point(x,sy))=color;
- if (sy+height-1>0 && sy+height-1<background.rows-1) background.at<Vec3b>(Point(x,sy+height-1))=color;
- }
- }
- for (int y=sy; y<sy+height; ++y) {
- if (y>0 && y<background.rows-1) {
- if (sx>0 && sx<background.cols-1) background.at<Vec3b>(Point(sx,y))=color;
- if (sx+width-1>0 && sx+width-1<background.cols-1) background.at<Vec3b>(Point(sx+width-1,y))=color;
- }
- }
- }
- void obtainTargets(const cv::Mat &background, const std::vector<cv::Mat> &hostiles, const std::vector<cv::Mat> &hostiles_2, std::vector<std::vector<float > > &hmatch) {
- //std::cout << "b.rows: " << background.rows << " b.cols: " << background.cols << std::endl;
- //std::cout << "h.rows: " << hostiles[0].rows << " h.cols: " << hostiles[0].cols << std::endl;
- Mat background_2; resize(background, background_2, Size(160,120), 0, 0, INTER_CUBIC);
- std::vector<std::vector<bool > > p; p.resize(320); for (int x=0;x<320;x++) { p[x].resize(240); }
- for (int x=0;x<320;x++) { for (int y=0;y<240;y++) { p[x][y]=false; }}
- // Obtain candidates by hierarchical decomposition, to avoid convolution of full tile over all pixels
- // Do a coarse 7x7 on 160x120, step 2x2
- for (int y=7*2; y<background_2.rows-7*2; y+=2) {
- for (int x=7*2; x<background_2.cols-7*2; x+=2) {
- Mat s(background_2, cv::Rect(x,y,7,7));
- float best_err=1000.0f;
- for (int i=0;i<6;i++) {
- float err=(norm(s,hostiles_2[i],CV_L2))/static_cast<double>(s.rows*s.cols);
- if (err<best_err) { best_err=err; }
- }
- if (best_err<30.0f) {
- for (int x2=x*2;x2<x*2+4;x2++) {
- for (int y2=y*2;y2<y*2+4;y2++) {
- p[x2][y2]=true;
- }
- }
- }
- }
- }
- for (int y=0; y<background.rows-13; y+=2) {
- for (int x=0; x<background.cols-13; x+=2) {
- if (p[x][y]) {
- Mat s(background, cv::Rect(x,y,13,13));
- float best_err=1000;
- for (int i=0;i<6;i++) {
- float err=(norm(s,hostiles[i],CV_L2))/static_cast<double>(s.rows*s.cols);
- if (err<hmatch[i][2]) {
- hmatch[i][2]=err;
- hmatch[i][0]=x; hmatch[i][1]=y;
- }
- if (err<best_err) { best_err=err; }
- }
- }
- }
- }
- }
- // From http://jepsonsblog.blogspot.in/2012/10/overlay-transparent-image-in-opencv.html
- void overlayImage(const cv::Mat &background, const cv::Mat &foreground, cv::Mat &output, cv::Point2i location) {
- background.copyTo(output);
- int maxy=0; if (location.y>0) { maxy=location.y; }
- for (int y=maxy; y<background.rows; ++y) {
- int fY=y-location.y; // because of the translation
- if(fY>=foreground.rows) break;
- int maxx=0; if (location.x>0) { maxy=location.x; }
- for (int x=maxx; x<background.cols; ++x) {
- int fX=x-location.x;
- if (fX>=foreground.cols) break;
- double opacity=((double)foreground.data[fY * foreground.step + fX * foreground.channels() + 3])/255.;
- for (int c=0; opacity>0 && c<output.channels(); ++c) {
- unsigned char foregroundPx=foreground.data[fY*foreground.step+fX*foreground.channels()+c];
- unsigned char backgroundPx=background.data[y*background.step+x*background.channels()+c];
- output.data[y*output.step+output.channels()*x+c]=backgroundPx*(1.-opacity)+foregroundPx*opacity;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement