⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capturebuf.cpp

📁 通过使机器人进行简单的图像识别
💻 CPP
字号:
#include "StdAfx.h"
#include "capturebuf.h"

HRESULT InitCaptureCard(CAPTUREPARAM param)
{
	HRESULT hr;
	if (FAILED(hr= DSStream_Initialize()))
		return hr;

	if (FAILED(hr= DSStream_ConnectDevice(param.cap_card, FALSE, param.cap_hwnd)))
		return hr;

	// 窗口显示区域
	RECT rc;
	if (param.cap_show)
	{
		rc.left= 0;
		rc.right= rc.left + param.cap_width;
		rc.top= 0;
		rc.bottom= rc.top + param.cap_height;
	}
	else
	{
		rc.left= rc.right= rc.top= rc.bottom= 0;
	}
	DSStream_SetWindowPos(param.cap_card, rc);

	// 设置图像格式
	DSStream_SetVideoStandard(param.cap_card, VideoStandard_PAL_D);
	VIDEOSTREAMINFO vsi;
	DSStream_GetVideoInfo(param.cap_card, &vsi, param.cap_pin);
	vsi.subtype= VideoSubType_RGB24;
	vsi.bmiHeader.biWidth= param.cap_width;
	vsi.bmiHeader.biHeight= param.cap_height;

	DSStream_SetVideoInfo(param.cap_card, vsi, param.cap_pin);

	DSStream_GetVideoInfo(param.cap_card, &vsi, param.cap_pin);
	// 设置对比度等参数
	DSStream_SetVideoPropertyValue(param.cap_card, VideoProperty_Saturation, 5000);
	DSStream_SetVideoPropertyValue(param.cap_card, VideoProperty_Brightness, 5000);
	DSStream_SetVideoPropertyValue(param.cap_card, VideoProperty_Contrast, 5000);
	DSStream_SetVideoPropertyValue(param.cap_card, VideoProperty_Hue, 5000);

	return S_OK;
}

void ReleaseCard(CAPTUREPARAM param)
{
	DSStream_DisconnectDevice(param.cap_card);
	DSStream_Uninitialize();
}

CCaptureBuf::CCaptureBuf(void)
: m_phdr(NULL)
, m_size(0)
{
}

CCaptureBuf::~CCaptureBuf(void)
{
	Free();
}

// 分配所需的内存空间
bool CCaptureBuf::Alloc(int cap_card)
{
	Free();
		
	if (FAILED(DSStream_GetCurrentDib(cap_card, NULL, &m_size)))
		return false;
	else
	{
		m_phdr= reinterpret_cast<BITMAPINFOHEADER*>(new unsigned char[m_size]);
		m_phdr->biBitCount= 16;
		m_phdr->biHeight= 240;
		m_phdr->biWidth= 320;
		return true;
	}
}

// 释放内存
void CCaptureBuf::Free(void)
{
	m_size= 0;

	delete[] m_phdr;
	m_phdr= NULL;
}

// 从采集卡数据流中更新缓冲区数据
bool CCaptureBuf::UpdateBuffer(int cap_card)
{
	if (SUCCEEDED(DSStream_GetCurrentDib(cap_card, reinterpret_cast<BYTE *>(m_phdr), &m_size)))
	{	
		long lPitch= 2 * m_phdr->biWidth;
		lPitch+= (4 - lPitch % 4) % 4;

		// 颠倒扫描线
		for (unsigned int y= 0; y < (m_phdr->biHeight / 2); y++)
		{
			unsigned short *psrc= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
			unsigned short *pdst= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + (m_phdr->biHeight - y - 1) * lPitch);
			for (unsigned int x= 0; x < (m_phdr->biWidth); x++)
			{
				__asm
				{
					mov esi, psrc;
					mov edi, pdst;

					mov ax, [esi];
					mov bx, [edi];
					mov [edi], ax;
					mov [esi], bx;

					add esi, 2;
					add edi, 2;
					mov psrc, esi;
					mov pdst, edi;
				}
			}
		}
		return true;
	}
	else
		return false;
}

bool CCaptureBuf::UpdateBuffer(LPI_DXSURFACE ps)
{
	long lPitch= 2 * m_phdr->biWidth;
	lPitch+= (4 - lPitch % 4) % 4;

	IMAGEMEMORY img;
	ps->LockImage(&img);

	if (img.bitcount == 16)
	{	// 565 to 555
		for (unsigned int y= 0; y < m_phdr->biHeight; y++)
		{
			unsigned short *pdst= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
			unsigned short *psrc= reinterpret_cast<unsigned short *>(img.pMemory + img.lPitch * y);
			for (unsigned int x= 0; x < m_phdr->biWidth; x++)
			{
				__asm
				{
					mov edi, pdst;
					mov esi, psrc;

					mov ax, [esi];

					mov bl, al;
					and bl, 0x1F;	// 3(0)B5 => bl

					shr ax, 1;		// 1(0)R5G6B4 => ax
					and al, 0x7FE0; // 1(0)R5G5B5(0) => ax

					or al, bl;		// 1(0)R5G5B5 => ax

					mov [edi], ax;

					add edi, 2;
					add esi, 2;

					mov pdst, edi;
					mov psrc, esi;				
				}
			}
		}
	}
	else if (img.bitcount == 32)
	{	// 888 to 555
		for (unsigned int y= 0; y < m_phdr->biHeight; y++)
		{
			unsigned short *pdst= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
			unsigned int *psrc= reinterpret_cast<unsigned int *>(img.pMemory + img.lPitch * y);
			for (unsigned int x= 0; x < m_phdr->biWidth; x++)
			{
				__asm
				{
					mov edi, pdst;
					mov esi, psrc;

					mov eax, [esi];
					
					mov ebx, eax;
					and ebx, 0x000000F8;		// b5 => ebx;

					mov ecx, eax;
					and ecx, 0x0000F800;		// g5 => ecx;

					and eax, 0x00F80000;		// r5 => eax;

					shr ebx, 3;
					shr ecx, 6;
					shr eax, 9;

					or eax, ebx;
					or eax, ecx;

					mov [edi], ax;

					add edi, 2;
					add esi, 4;

					mov pdst, edi;
					mov psrc, esi;
				}
			}
		}		
	}

	ps->UnlockImage();

	return true;
}

// 图象转换, pBMPHdr为采集卡的数据(16位)
void CCaptureBuf::Bitmap2Surface(LPI_DXSURFACE ps)
{
	long lPitch= 2 * m_phdr->biWidth;
	lPitch+= (4 - lPitch % 4) % 4;

	IMAGEMEMORY img;
	ps->LockImage(&img);
	if (img.bitcount == 16)
	{	// 555 to 565
		for (unsigned int y= 0; y < m_phdr->biHeight; y++)
		{
			unsigned short *psrc= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
			unsigned short *pdst= reinterpret_cast<unsigned short *>(img.pMemory + img.lPitch * y);
			for (unsigned int x= 0; x < m_phdr->biWidth; x++)
			{
				__asm
				{
					mov esi, psrc;
					mov edi, pdst;

					xor eax, eax;
					xor ebx, ebx;

					mov ax, [esi];
					mov bx, ax;

					shl ax, 1;
					and ax, 0xFFC0;	// convert to  R5G5G1(0)B5(0)
					and bx, 0x001F;	// convert to  R5(0)G6(0)B5
					or ax, bx;		// convert to  R5G6B6 => ax

					mov [edi], ax;

					add psrc, 2;
					add pdst, 2;
				}
			}
		}
	}
	else
	{	// 555 to 888
		for (unsigned int y= 0; y < m_phdr->biHeight; y++)
		{
			unsigned short *psrc= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(m_phdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
			unsigned int *pdst= reinterpret_cast<unsigned int *>(img.pMemory + img.lPitch * y);
			for (unsigned int x= 0; x < m_phdr->biWidth; x++)
			{
				__asm
				{
					mov esi, psrc;
					mov edi, pdst;

					xor eax, eax;
					xor ebx, ebx;

					mov ax, [esi];
					
                    shl eax, 3;
					mov bl, al;		// B5B3(0) => bl;
					
					xor al, al;
					shl eax, 3;
					mov bh, ah;		// G5G3(0) => bh;

					xor ah, ah;
					shl eax, 3;
					mov ah, bh;
					mov al, bl;		// R5R3(0)G5G3(0)B5B3(0) => eax

					mov [edi], eax;

					add psrc, 2;
					add pdst, 4;
				}
			}
		}		
	}

	ps->UnlockImage();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -