C++非纯色背景实时抠像

通过USB摄像头进行非纯色背景实时抠像

void CiPhotoDlg::OnPaint()
{
	CPaintDC dc(this);
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		if (mattingContent.flag)
		{
			CImage img;
			cv::Mat mattingRGB;
			// 将 BGR 转换为 RGB
			cv::cvtColor(mattingContent.merge_mat, mattingRGB, cv::COLOR_BGR2RGB);
			// 创建 CImage 对象,24位即每像素3个字节
			img.Create(mattingRGB.cols, mattingRGB.rows, 24);

			// 确保 CImage 数据与 OpenCV Mat 数据的通道顺序匹配
			for (int y = 0; y < mattingRGB.rows; ++y)
			{
				BYTE* pDest = reinterpret_cast<BYTE*>(img.GetPixelAddress(0, y));
				const BYTE* pSrc = mattingRGB.ptr<BYTE>(y);
				// 确保 BGR-RGB 通道正确
				for (int x = 0; x < mattingRGB.cols; ++x)
				{
					pDest[3 * x] = pSrc[3 * x + 2];
					pDest[3 * x + 1] = pSrc[3 * x + 1];
					pDest[3 * x + 2] = pSrc[3 * x];
				}
			}

			// 获取窗口矩形并绘制图像
			CRect rect;
			GetClientRect(&rect);
			img.Draw(dc.m_hDC, 0, 0, rect.Width(), rect.Height(), 0, 0, img.GetWidth(), img.GetHeight());
		}
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CiPhotoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}
void CiPhotoDlg::OnTimer(UINT_PTR nIDEvent)
{
	if (nIDEvent == 1 && cap.isOpened())
	{
		cap >> frame;
		if (!frame.empty())
		{
			rvm->detect(frame, mattingContent, 0.6f);
			Invalidate();
		}
	}
	CDialogEx::OnTimer(nIDEvent);
}
void CiPhotoDlg::OnBnClickedButton1()
{
	CDC* pDC = GetDC();
	CRect rect;
	GetClientRect(&rect);  // Get the size of the dialog window

	// Create a memory device context and a compatible bitmap
	CDC memDC;
	memDC.CreateCompatibleDC(pDC);
	CBitmap bmp;
	bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
	CBitmap* pOldBitmap = memDC.SelectObject(&bmp);

	// Copy the dialog's content to the memory device context
	memDC.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);

	// Convert the bitmap to a DIB (device-independent bitmap) for OpenCV
	BITMAP bmpInfo;
	bmp.GetBitmap(&bmpInfo);
	BITMAPINFOHEADER bi = { sizeof(BITMAPINFOHEADER), bmpInfo.bmWidth, -bmpInfo.bmHeight, 1, 32, BI_RGB, 0, 0, 0, 0, 0 };
	std::vector<BYTE> bitmapData(bmpInfo.bmWidthBytes * bmpInfo.bmHeight);
	GetDIBits(memDC, bmp, 0, bmpInfo.bmHeight, &bitmapData[0], (BITMAPINFO*)&bi, DIB_RGB_COLORS);

	// Create an OpenCV Mat from the bitmap data
	cv::Mat mat(bmpInfo.bmHeight, bmpInfo.bmWidth, CV_8UC4, &bitmapData[0]);
	cv::cvtColor(mat, mat, cv::COLOR_BGRA2BGR);  // Convert from BGRA to BGR format

	// Generate a filename based on the current system time
	time_t now = time(0);
	struct tm tstruct;
	char buf[80];
	localtime_s(&tstruct, &now);
	strftime(buf, sizeof(buf), "%Y%m%d_%H%M%S", &tstruct);

	// Get the executable's directory path
	TCHAR exePath[MAX_PATH];
	GetModuleFileName(NULL, exePath, MAX_PATH);
	CString exeDirPath(exePath);
	exeDirPath = exeDirPath.Left(exeDirPath.ReverseFind('\\') + 1);  // Extract directory path

	// Combine the directory path with the timestamp to form the complete file path
	CString filePath;
	filePath.Format(_T("%s%s.jpg"), exeDirPath, buf);

	// Convert CString to std::string
	CT2CA pszConvertedAnsiString(filePath);
	std::string strStd(pszConvertedAnsiString);

	// Save the Mat as an image file
	cv::imwrite(strStd, mat);

	AfxMessageBox(_T("保存成功"));

	// Cleanup
	memDC.SelectObject(pOldBitmap);
	ReleaseDC(pDC);
}

在这里插入图片描述

在这里插入图片描述
下载链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值