opencv 检测 键盘_C++ 利用opencv识别飞车舞蹈按键
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
本来我玩飞车舞蹈技术挺好的,有时候不稳定。有一次被人嘲讽了,当时心中不忿,就写了个这个
另外我对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识别飞车舞蹈按键相关推荐
- opencv 检测几何图形_使用OpenCV + ConvNets检测几何形状
opencv 检测几何图形 A simple yet powerful pipeline for detecting shapes in scanned documents 一个简单而强大的管道,用于 ...
- java opencv 阀值分割_利用OpenCV实现局部动态阈值分割
利用OpenCV实现局部动态阈值分割,参考Halcon dyn_threshold算子的思路实现. #include "dialog.h" #include #include &q ...
- opencv raw转rgb_利用opencv将raw转换为rgb
最近工作中碰到将.raw格式文件转换为彩图格式文件.待转换的.raw格式文件不带有图像的宽高等信息,只有图像像素值信息,利用opencv接口无法直接读取.网上查的方法都无法满足我的需求,经过各种尝试终 ...
- opencv 检测 键盘_ubuntu+vscode 测试运行opencv
之前ubuntu配置好了opencv,今天测试运行一下. 1.创建一个文件夹opencv+test 2.在文件夹内打开终端,创建一个cpp文件,再放一张图片. touch mian.cpp 3.vim ...
- c++ opencv实现区域填充_利用opencv之为图像添加边框
我们经常会有对图像边缘做扩展的需求.比如 希望卷积后得到的矩阵大小不变 希望改变图像大小,但是不改变宽高比 opencv实现 opencv中使用copyMakeBorder()来完成这一功能 api ...
- python opencv 录制视频_Python利用opencv实现录制视频
import cv2 import threading #python 多线程操作库 class RecordingThread(threading.Thread): def __init__( ...
- python opencv天空提取_python利用opencv实现印章的提取
抽空写了下,怕找不到了,做个备份,直接上代码,嗯,自己能看懂就喜欢这种感觉: #coding:utf-8 import cv2 import numpy as np #加载图片 image = cv2 ...
- 如何利用OpenCV寻找轮廓的中心?
简 介: 本文介绍了利用OpenCV和Python编程来计算形状轮廓的中心点.当然后面还会继续给出如何通过轮廓来分辨物体形状种类,以及对于各自的颜色进行标准. 关键词: OpenCV,contours ...
- python用opencv计算汽车间距_计算机视觉:利用OpenCV和Python进行车辆计数详细步调...
本教程我将分享几个简单步调剂释如何使用OpenCV进行Python对象计数. 需要安装一些软件: Python 3OpennCV 1.了解Opencv从摄像头获得视频的Python脚本 import ...
最新文章
- 洛谷 P2415 集合求和【数学公式/模拟】
- 傅立叶变换—FFT(cuda实现)
- C#中对泛型List进行分组输出元素
- oracle使用sqlplus查询sql格式
- [Java基础]Map集合基础
- 名创优品向港交所提交上市申请书
- linux cent os7,Cent OS 7系统目录结构
- 中国水龙头市场趋势报告、技术动态创新及市场预测
- 掌控安全Web安全微专业笔记
- 超声波传感器测距实验430
- 【win10系统重装】
- 听说CDN高防和高防IP是服务器安全的“翘楚”,那么你知道这二者的区别吗?
- vue2.0中的路由传值
- 基于python的个人博客系统的设计开题报告_基于JavaSSM框架的个人博客系统设计与实现开题报告...
- 诺顿ghost使用教程
- Win10电脑创建本地网站
- 虚拟机命令里面的光标不动了怎么办_Linux 11个炫酷的终端命令!你知道几个?
- 公众号seo排名优化技术,公众号名称优化排名
- IT人的微信自媒体--- 杰天空, 走在寻找创意的路上
- 基于Springboot+Vue+小程序学生课程考勤系统设计
热门文章
- Android移动网络设置
- 餐饮 美食 食物cc0高清摄影图片素材推荐 精品 小众
- Ubuntu安装Multi-Agent Particle Environment(MPE)
- 揭秘12306技术改造(三):传统框架云化迁移到内存数据平台
- Solidworks2018与Mentor EEVX2.3联合设计3D PCB图像
- 5个区块链正在发挥作用的行业
- ChatGPT提问技巧 笔记
- 在r语言使用python_在R中导入python模块
- 浅谈考雅思(谨以此总结自己经验教训)
- android进阶篇02、RecyclerView回收复用机制源码解析,h5移动端开发进行定位