自动试玩 - 识别虚线框

识别虚线框


QQ 282397369

需求

老革命碰到新问题,用户发现在试玩的时候,有一个平台需要按住虚框进行操作,目前的脚本还没有这个功能,需要实现一下下。
不怕客户没爱好,就怕客户没需求。
在这里插入图片描述

实现

首先是颜色过滤,然后找连通域,再拼成矩形框数据。当然,矩形框数据只需找上下左右4个坐标分量,这个可以通过投影找最大两个数值来确定。
核心实现,肯定还得C来
考虑实用性,把二值化这个步骤用字符串来参数化,这样就可以实现彩色、灰度、通道方式过滤。
先设计一个函数:

TRect __fastcall CvHelper::GetRect_Dash(cv::Mat& srcMat, UnicodeString binaryMethod) {
	TRect result(-1, -1, -1, -1);
	UnicodeString type = THelper::String::GetStringAt(binaryMethod, L",", 0).Trim();
	UnicodeString value1 = THelper::String::GetStringAt(binaryMethod, L",", 1).Trim();
	UnicodeString value2 = THelper::String::GetStringAt(binaryMethod, L",", 2).Trim();
	cv::Mat binaryMat;
	int v1 = ::TTypeConvert::Str2Int(value1);
	if(THelper::String::IsSame(L"Color", type, !DRGRAPH_FLAG_SENSITIVE)) {
		if(value2.Length()) {
			int delta = ::TTypeConvert::Str2Int(value2);
			binaryMat = CvHelper::BuildTransMaskMat(srcMat, TColor(v1), delta);
		} else
			binaryMat = CvHelper::BuildTransMaskMat_ColorPass(srcMat, v1);
	} else if(THelper::String::IsSame(L"Gray", type, !DRGRAPH_FLAG_SENSITIVE)) {
		if(value2.Length()) {
			int delta = ::TTypeConvert::Str2Int(value2);
			binaryMat = CvHelper::BuildTransMaskMat(srcMat, BYTE(v1), delta);
		} else
			binaryMat = CvHelper::BuildTransMaskMat_GRAY(srcMat, BYTE(v1));
	} else if(THelper::String::IsSame(L"Channel", type, !DRGRAPH_FLAG_SENSITIVE)) {
		NChannelType channel = THelper::String::IsSame(L"RED", value1, !DRGRAPH_FLAG_SENSITIVE) ? nctRed :
							   THelper::String::IsSame(L"BLUE", value1, !DRGRAPH_FLAG_SENSITIVE) ? nctBlue : nctGreen;
		int delta = ::TTypeConvert::Str2Int(value2);
		binaryMat = CvHelper::BuildTransMaskMat_Channel(srcMat, channel, delta);
	}
	if(binaryMat.empty())
		return result;
	CvHelper::Debug::LogMat(srcMat, L"虚线框识别 - 原图");
	CvHelper::Debug::LogMat(binaryMat, L"虚线框识别 - 二值图");
	CvRects rects = CvHelper::GetAllDomain(binaryMat, nssX, L"", CV_RETR_LIST);
	CvHelper::Debug::LogMatWithRects(srcMat, rects);
	int * rowValue = new int[srcMat.rows];
	int * colValue = new int[srcMat.cols];
	ZeroMemory(rowValue, srcMat.rows * sizeof(int));
	ZeroMemory(colValue, srcMat.cols * sizeof(int));
	for(int i = rects.size() - 1; i >= 0; --i) {
		CvRect r = rects[i];
		if(r.height > maxLength || r.width > maxLength)
			rects.erase(rects.begin() + i);
		else {
			int x = r.x + r.width / 2;
			int y = r.y + r.height / 2;
			rowValue[y] += 1;
			colValue[x] += 1;
		}
	}
	int left = localGetMaxIndex(colValue, srcMat.cols);
	int right = -1;
	if(left >= 0) {
		colValue[left] = 0;
		right = localGetMaxIndex(colValue, srcMat.cols);
	}
	int top = GetMaxIndex(rowValue, srcMat.rows);
	int bottom = -1;
	if(top >= 0) {
		rowValue[top] = 0;
		bottom = GetMaxIndex(rowValue, srcMat.rows);
	}
	delete rowValue;
	delete colValue;
	if(left < 0 || right < 0 || top < 0 || bottom < 0)
		return result;
	result.left = std::min(left, right);
	result.top = std::min(top, bottom);
	result.right = std::max(left, right);
	result.bottom = std::max(top, bottom);
	CvHelper::Debug::LogMatWithRects(srcMat, rects);
	return result;
}

经测试,可以正确识别出虚线框
在这里插入图片描述

LUA调用

增加一个API函数GetRect_Dash供LUA调用,返回矩形区域即可。

	local t, x, y, w, h = cv:GetRect_Dash(realTimeMat, "Channel, BLUE, 80")
	if(x > 0) then
		Click(string.format("%d, %d", x + w / 2, y + h / 2))
	end

结果:
在这里插入图片描述
如此甚好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值