加载中…
正文 字体大小:

QQ自动找茬的原理

(2012-11-16 22:00:11)
标签:

杂谈

1.角点定位,左右图像差,并利用滤波器去除噪音,这里代码用windows下的GUI库为例;

下载地址:http://pan.baidu.com/share/link?shareid=151549&uk=3120909006

QQ自动找茬的原理

//Created by pritry

void FindBmpFromHwnd(HWND hWnd, bool bAuto) 

 if(!::IsWindow(hWnd)) return;
 
 HDC hDC = ::GetWindowDC(hWnd); 
 ASSERT(hDC); 

 HDC hMemDC = ::CreateCompatibleDC(hDC); 
 ASSERT(hMemDC); 

 RECT rc; 
 ::GetWindowRect(hWnd, &rc); 

 int nScreenX = (m_nPicSizeDis+2*m_nPicSizeX + 3) / 4 * 4;
 int nScreenY = m_nPicSizeY;

 HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC, nScreenX, nScreenY); 
 ASSERT(hBitmap); 

 HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, hBitmap); 
 ::BitBlt(hMemDC, 0, 0, nScreenX, nScreenY, ::GetDC(hWnd), m_nGameOffsetX, m_nGameOffsetY, SRCCOPY);  //498*448

 BITMAP bitmap = {0}; 
 ::GetObject(hBitmap, sizeof(BITMAP), &bitmap); 
 BITMAPINFOHEADER bi = {0}; 
 BITMAPFILEHEADER bf = {0}; 

 CONST int nBitCount = 24; 
 bi.biSize = sizeof(BITMAPINFOHEADER); 
 bi.biWidth = bitmap.bmWidth; 
 bi.biHeight = bitmap.bmHeight; 
 bi.biPlanes = 1; 
 bi.biBitCount = nBitCount; 
 bi.biCompression = BI_RGB; 
 DWORD dwSize = ((bitmap.bmWidth * nBitCount + 31) / 32) * 4 * bitmap.bmHeight; 

 HANDLE hDib = GlobalAlloc(GHND, dwSize + sizeof(BITMAPINFOHEADER)); 
 LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); 
 *lpbi = bi; 

 ::GetDIBits(hMemDC, hBitmap, 0, bitmap.bmHeight, (BYTE*)lpbi + sizeof(BITMAPINFOHEADER), (BITMAPINFO*)lpbi, DIB_RGB_COLORS); 

 BYTE* p = (BYTE*)lpbi + sizeof(BITMAPINFOHEADER);

 int offset = m_nPicSizeX + m_nPicSizeDis + 1; 

 memset(m_pScreenData, 0 , m_nScreenHeight * m_nScreenWidth * 3);

 for(int j = 4; j < m_nPicSizeY-4; ++j)
 {
  for(int i = 4; i < m_nPicSizeX-4; ++i)
  {
   p[j*nScreenX*3+i*3]   = abs(p[j*nScreenX*3+i*3]   - p[j*nScreenX*3+i*3+offset*3]);
   p[j*nScreenX*3+i*3+1] = abs(p[j*nScreenX*3+i*3+1] - p[j*nScreenX*3+i*3+offset*3+1]);
   p[j*nScreenX*3+i*3+2] = abs(p[j*nScreenX*3+i*3+2] - p[j*nScreenX*3+i*3+offset*3+2]);

   if(p[j*nScreenX*3+i*3]   > GAME_WRONG_THRESH ||
      p[j*nScreenX*3+i*3+1] > GAME_WRONG_THRESH ||
      p[j*nScreenX*3+i*3+2] > GAME_WRONG_THRESH)
   {
    SetScreenPixel(i, j, GREEN);
   }
  }
 }

 GlobalUnlock(hDib); 
 GlobalFree(hDib); 

 ::SelectObject(hMemDC, hOldBmp); 
 ::DeleteObject(hBitmap);     
 ::DeleteObject(hMemDC); 
 ::ReleaseDC(hWnd, hDC); 
}
 


2.图像矩形化处理,减少干扰角点和噪音小块;
QQ自动找茬的原理

//Created by pritry

for(int j = 1; j < m_nScreenHeight-1; ++j)
  {
   for(int i = 1; i < m_nScreenWidth-1; ++i)
   {
    if(GetScreenPixel(i, j).rgbGreen == 0)
    {
     if(GetScreenPixel(i-1, j).rgbGreen +
      GetScreenPixel(i+1, j).rgbGreen +
      GetScreenPixel(i, j-1).rgbGreen +
      GetScreenPixel(i, j+1).rgbGreen > 500)
      SetScreenPixel(i, j, GREEN);
    }
    else
    {
     if(GetScreenPixel(i-1, j).rgbGreen +
      GetScreenPixel(i+1, j).rgbGreen +
      GetScreenPixel(i, j-1).rgbGreen +
      GetScreenPixel(i, j+1).rgbGreen == 0)
      SetScreenPixel(i, j, BLACK);
    }
   }
  }

 
3.递归投影法计数投影山峰个数而区分单一连通体,此时正确率有80%左右,不要采用聚类分类方法,实际中并不容易定义各个连通体的区分规则;

//Created by pritry

inline int CountSeparatedRectThresh(int* nSample, int nSampleSize, std::vector<int>* pThresh)
{
 ASSERT(pThresh != NULL);
 pThresh->clear();

 int nLast = 0;
 int i = 0;

 while(i < nSampleSize)
 {
  while(i < nSampleSize && nSample[i] == 0)
   ++i;

  if(i >= nSampleSize)
   break;

  if(nLast > 0)
   pThresh->push_back((nLast+i)>>1);

  while(i < nSampleSize && nSample[i] > 0)
   ++i;
  
  if(i >= nSampleSize)
   break;

  nLast = i;
 }

 return (int)pThresh->size();

}

 
4.计算单连通域质心位置,获取hook鼠标位置坐标完成标准识别过程
5.如果标准识别过程失败,进行角点提取并过滤,进行第二步识别流程,计算其角点连通个数与双连通问题减少失败概率;
QQ自动找茬的原理

QQ自动找茬的原理

QQ自动找茬的原理



 

0

阅读 评论 收藏 转载 喜欢 打印举报
已投稿到:
前一篇:Harris
后一篇:Jigsaw
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

    < 前一篇Harris
    后一篇 >Jigsaw
      

    新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有