该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

本来我玩飞车舞蹈技术挺好的,有时候不稳定。有一次被人嘲讽了,当时心中不忿,就写了个这个

另外我对opencv不熟..写这个就是看了百度使用opencv基础函数的文章。。。,有opencv复杂问题不要问我谢谢...

C++可以随便问

贴出核心代码

void CJuzQQFeiCheDlg::OnBnClickedButton3()

{

int nCatImageSize_x = 355 + 30;

int nCatImageSize_y = 45;

int nCatImageSize_left = 205 - 20;

int nCatImageSize_top = 488;

//创建兼容位图

HBITMAP mCloneGameBitMap = CreateCompatibleBitmap(gameDc, nCatImageSize_x, nCatImageSize_y);

//创建兼容 dc

HDC mCloneGameDc = ::CreateCompatibleDC(gameDc);//创建当前上下文的兼容dc(内存DC)

HBITMAP hOldBitmap = (HBITMAP)::SelectObject(mCloneGameDc, mCloneGameBitMap);//将位图加载到内存DC

//复制位图到刚创建出来的图

BitBlt(mCloneGameDc, 0, 0, nCatImageSize_x, nCatImageSize_y, gameDc, nCatImageSize_left, nCatImageSize_top, SRCCOPY); //213 450是起点

int nCountNum = 0;

Mat sourceImage ;

if (HBitmapToMat(mCloneGameBitMap, sourceImage))

{

//取到图片先灰度化

Mat hSrcImage;

Mat copyImg = sourceImage.clone();

cvtColor(sourceImage, hSrcImage, CV_BGR2GRAY);//原图变灰度

threshold(hSrcImage, hSrcImage, 140, 255, CV_THRESH_BINARY);//对图像进行二值化

//2.查找轮廓

vector> contours2;

findContours(hSrcImage, contours2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);//最外层轮廓

//删掉面积小的

vector >::iterator iter = contours2.begin();

for (; iter != contours2.end();)

{

double g_dConArea = contourArea(*iter);

if (g_dConArea < 500) //面积500一下都不要

{

iter = contours2.erase(iter);

}

else

{

++iter;

}

}

//全部变成色

int nr = copyImg.rows;

int nl = copyImg.cols * copyImg.channels();

for (int k = 0; k < nr; k++)

{

uchar* outData = copyImg.ptr(k);

for (int i = 0; i < nl; i++)

{

outData[i] = 255;

}

}

drawContours(copyImg, contours2, -1, Scalar(0, 0, 255), -1, 8);

cvtColor(copyImg, copyImg, CV_BGR2GRAY);//原图变灰度

Mat tempImage,caoSrcImage;

feiCheKey.clear();//清空之前的按键

while (true)

{

caoSrcImage = copyImg(Rect(0, 0, hSrcImage.cols, hSrcImage.rows));

int nFindNowNum = 0;

bool isSave = false;

//开始匹配图像

for (int i = 0; i < 4; i++)

{

tempImage = g_DirectionImage[i](Rect(0, 0, g_DirectionImage[i].cols, g_DirectionImage[i].rows));

cvtColor(tempImage, tempImage, CV_BGR2GRAY);//原图变灰度

int result_cols = caoSrcImage.cols - tempImage.cols + 1;

int result_rows = caoSrcImage.rows - tempImage.rows + 1;

if (result_cols >= 0 && result_rows >= 0 && caoSrcImage.cols > tempImage.cols && caoSrcImage.rows > tempImage.rows)

{

cv::Mat result = cv::Mat(result_cols, result_rows, CV_32FC1);

cv::matchTemplate(caoSrcImage, tempImage, result, CV_TM_SQDIFF);

double minVal, maxVal;

cv::Point minLoc, maxLoc, matchLoc;

cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

matchLoc = minLoc;

//if (minVal >= 500000) //左键可能被误认成下键 47万左右

if (minVal >= 400000)

{

nFindNowNum++;

}

else

{

FEICHE_KEYINFO feicheInfo;

feicheInfo.mX = matchLoc.x;

feicheInfo.mY = matchLoc.y;

feicheInfo.nDir = i;

feicheInfo.mXS = minVal;

feiCheKey.push_back(feicheInfo);

rectangle(caoSrcImage, Point(matchLoc.x, matchLoc.y), Point(matchLoc.x + tempImage.cols, matchLoc.y + tempImage.rows), Scalar(255, 255, 255), -1, 8);

if (minVal >= 300000) //统计出现300000及以上的按键图

{

isSave = true;

}

}

}

}

if (nFindNowNum >= 4)

{

//feiCheKey 排序

imshow("sss", caoSrcImage);

std::sort(feiCheKey.begin(), feiCheKey.end(), FeiCheSort);

int count = feiCheKey.size();

CString shibieTitle, strXS, savePath;

shibieTitle.Format(L"一共识别出:%d 键 分别是:", count);

for (int i = 0; i < count; i++)

{

int minNum = feiCheKey[i].nDir;

int testXS = feiCheKey[i].mXS;

strXS.Format(L"(%d)", testXS);

if (minNum == 0)

{

shibieTitle = shibieTitle + L" 上";

}

else if (minNum == 1)

{

shibieTitle = shibieTitle + L" 下";

}

else if (minNum == 2)

{

shibieTitle = shibieTitle + L" 左";

}

else if (minNum == 3)

{

shibieTitle = shibieTitle + L" 右";

}

shibieTitle = shibieTitle + strXS;

savePath = savePath + strXS;

}

//更新文本

CStatic *testShow = (CStatic*)GetDlgItem(IDC_STATIC_SHOW);

if (count <= 0)

{

RECT rc;

::GetClientRect(g_GameWindwosAdd, &rc);

shibieTitle.Format(L"分析失败 目标窗口【长:%d 宽:%d】", rc.right, rc.bottom);

}

else

{

if (isSave)

{

CString path, numPath;

static int num = 0;

numPath.Format(L"_%d.jpg", num++);

path = L"d:\\moni\\" + savePath + numPath;

string Savepath = CStringA(path);

imwrite(Savepath, copyImg);

}

}

testShow->SetWindowTextW(shibieTitle);

//按下按键

for (int i = 0; i < count; i++)

{

int minNum = feiCheKey[i].nDir;

if (minNum == 0)

{

OutputDebugString(L"上");

juzKey.KEYKEY(VK_UP);

}

else if (minNum == 1)

{

OutputDebugString(L"下");

juzKey.KEYKEY(VK_DOWN);

}

else if (minNum == 2)

{

OutputDebugString(L"左");

juzKey.KEYKEY(VK_LEFT);

}

else if (minNum == 3)

{

OutputDebugString(L"右");

juzKey.KEYKEY(VK_RIGHT);

}

}

break;

}

}

}

//底部居中显示获取到的图

RECT clientRt;

GetClientRect(&clientRt);

int nClientPosx = (clientRt.right / 2) - (nCatImageSize_x / 2);

int nClientPosy = clientRt.bottom - nCatImageSize_y - 10;

//恢复到本窗口

BitBlt(theDc->m_hDC, nClientPosx, nClientPosy , nCatImageSize_x, nCatImageSize_y, mCloneGameDc, 0, 0, SRCCOPY);

//恢复内存原始数据

::SelectObject(mCloneGameDc, hOldBitmap);

//删除资源,防止泄漏

::DeleteObject(hOldBitmap);

::DeleteDC(mCloneGameDc);

}

原理很简单,获取飞车的窗口句柄,在800*600的情况下 截图到位图中。位图转成opencv的mat开始分析

利用模板匹配的方式进行匹配。目前分析成功率为98%以上

最后的话模拟按键就可以了 (这里坑了我一下,我向飞车窗口投递按键消息没反应。后面才想起来...d3d游戏有

一套自己的处理按键方式,为了更加快速的处理 而不经过微软的消息队列。有俩种方式实现按键,一种是hook d3d的DirectInput 这种方式可以后台模拟按键。还有一种是驱动模拟按键,我这里选的是驱动,只能前台模拟)

最后,效果图

opencv 检测 键盘_C++ 利用opencv识别飞车舞蹈按键相关推荐

  1. opencv 检测几何图形_使用OpenCV + ConvNets检测几何形状

    opencv 检测几何图形 A simple yet powerful pipeline for detecting shapes in scanned documents 一个简单而强大的管道,用于 ...

  2. java opencv 阀值分割_利用OpenCV实现局部动态阈值分割

    利用OpenCV实现局部动态阈值分割,参考Halcon dyn_threshold算子的思路实现. #include "dialog.h" #include #include &q ...

  3. opencv raw转rgb_利用opencv将raw转换为rgb

    最近工作中碰到将.raw格式文件转换为彩图格式文件.待转换的.raw格式文件不带有图像的宽高等信息,只有图像像素值信息,利用opencv接口无法直接读取.网上查的方法都无法满足我的需求,经过各种尝试终 ...

  4. opencv 检测 键盘_ubuntu+vscode 测试运行opencv

    之前ubuntu配置好了opencv,今天测试运行一下. 1.创建一个文件夹opencv+test 2.在文件夹内打开终端,创建一个cpp文件,再放一张图片. touch mian.cpp 3.vim ...

  5. c++ opencv实现区域填充_利用opencv之为图像添加边框

    我们经常会有对图像边缘做扩展的需求.比如 希望卷积后得到的矩阵大小不变 希望改变图像大小,但是不改变宽高比 opencv实现 opencv中使用copyMakeBorder()来完成这一功能 api ...

  6. python opencv 录制视频_Python利用opencv实现录制视频

    import cv2 import threading    #python 多线程操作库 class RecordingThread(threading.Thread): def __init__( ...

  7. python opencv天空提取_python利用opencv实现印章的提取

    抽空写了下,怕找不到了,做个备份,直接上代码,嗯,自己能看懂就喜欢这种感觉: #coding:utf-8 import cv2 import numpy as np #加载图片 image = cv2 ...

  8. 如何利用OpenCV寻找轮廓的中心?

    简 介: 本文介绍了利用OpenCV和Python编程来计算形状轮廓的中心点.当然后面还会继续给出如何通过轮廓来分辨物体形状种类,以及对于各自的颜色进行标准. 关键词: OpenCV,contours ...

  9. python用opencv计算汽车间距_计算机视觉:利用OpenCV和Python进行车辆计数详细步调...

    本教程我将分享几个简单步调剂释如何使用OpenCV进行Python对象计数. 需要安装一些软件: Python 3OpennCV 1.了解Opencv从摄像头获得视频的Python脚本 import ...

最新文章

  1. BZOJ-1005 明明的烦恼
  2. 用css3简单实现进度条
  3. 哈尔滨工程大学智能科学与工程学院成功举办了“一院一节“暨十二届极速挑战智能车总决赛
  4. 联想e550笔记本怎么样_预算5000-6000元笔记本电脑推荐(学生/入门/小白选购)*十二月更新...
  5. Android应用开发—如何解决handler的警告:Handler Class Should be Static or Leaks Occur
  6. 卸载mysql数据库命令,值得推荐!
  7. 2023武汉大学计算机考研信息汇总
  8. Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level. java.lang.Il
  9. Android签名验证与反调试机制的对抗技术
  10. android 下划线跟文字一样长,TextView 下划线 自动根据文字内容改变长度
  11. 趣头条爬虫(以财经频道为例)
  12. MPI并行编程: 矩阵乘法,积分计算,PSPR排序
  13. 【终极之战】基于Vue3+Vant3造一个网页版的类掘金app项目 - 个人主页
  14. 已解决mybatis报错:Invalid bound statement (not found)
  15. MFC对话框程序添加弹窗进度条提示
  16. linux静音,如何在Ubuntu终端中静音/禁用硬件提示音
  17. Richard Stallman称Ubuntu为木马
  18. APP自动化简单理解(在python中实现简单的app自动化框架)
  19. MIT_BIH数据库介绍
  20. GAN之父Ian Goodfellow离职苹果:不想重返办公室工作

热门文章

  1. 好用的三维绘图软件CREO学习直线
  2. Unity3D常用设计模式之工厂模式
  3. idea插件translation无法使用谷歌翻译和Chrome浏览器翻译无法使用解决方案
  4. Linux安装mysql报错:Header V4 RSA/SHA256 Signature, key ID 3a79bd29: NOKEY
  5. 【数论知识】1:和1-n中的所有质数有关的算法(朴素版+升级版)
  6. SSL-DoS攻击工具——thc-ssl-dos
  7. 软件序列号、验证码备忘
  8. 《实用机器学习》(孙亮 黄倩.著)笔记——第一章 引论
  9. 最新QQ空间免费皮肤代码
  10. recharts中Legend的margin属性设置无效