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

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

另外我对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. 洛谷 P2415 集合求和【数学公式/模拟】
  2. 傅立叶变换—FFT(cuda实现)
  3. C#中对泛型List进行分组输出元素
  4. oracle使用sqlplus查询sql格式
  5. [Java基础]Map集合基础
  6. 名创优品向港交所提交上市申请书
  7. linux cent os7,Cent OS 7系统目录结构
  8. 中国水龙头市场趋势报告、技术动态创新及市场预测
  9. 掌控安全Web安全微专业笔记
  10. 超声波传感器测距实验430
  11. 【win10系统重装】
  12. 听说CDN高防和高防IP是服务器安全的“翘楚”,那么你知道这二者的区别吗?
  13. vue2.0中的路由传值
  14. 基于python的个人博客系统的设计开题报告_基于JavaSSM框架的个人博客系统设计与实现开题报告...
  15. 诺顿ghost使用教程
  16. Win10电脑创建本地网站
  17. 虚拟机命令里面的光标不动了怎么办_Linux 11个炫酷的终端命令!你知道几个?
  18. 公众号seo排名优化技术,公众号名称优化排名
  19. IT人的微信自媒体--- 杰天空, 走在寻找创意的路上
  20. 基于Springboot+Vue+小程序学生课程考勤系统设计

热门文章

  1. Android移动网络设置
  2. 餐饮 美食 食物cc0高清摄影图片素材推荐 精品 小众
  3. Ubuntu安装Multi-Agent Particle Environment(MPE)
  4. 揭秘12306技术改造(三):传统框架云化迁移到内存数据平台
  5. Solidworks2018与Mentor EEVX2.3联合设计3D PCB图像
  6. 5个区块链正在发挥作用的行业
  7. ChatGPT提问技巧 笔记
  8. 在r语言使用python_在R中导入python模块
  9. 浅谈考雅思(谨以此总结自己经验教训)
  10. android进阶篇02、RecyclerView回收复用机制源码解析,h5移动端开发进行定位