当前位置:首页 > 智能硬件 > 智能硬件
[导读]前言:随着计算机软件、硬件技术的日新月异的发展和普及,人类已经进入一个高速发展的信息化时代,人类大概有80%的信息来自图像,科学研究、技术应用中图像处理技术越来越成为不可缺少的手段。图像处理所涉及的领域有

前言:随着计算机软件、硬件技术的日新月异的发展和普及,人类已经进入一个高速发展的信息化时代,人类大概有80%的信息来自图像,科学研究、技术应用中图像处理技术越来越成为不可缺少的手段。图像处理所涉及的领域有军事应用、医学诊断、工业监控、物体的自动分检识别系统等等,这些系统无不需要计算机提供实时动态,效果逼真的图像。

基于图像采集卡的视频图像处理系统

计算机图像处理系统从系统层次上可分为高、中、低档三个层次,目前一般比较普及的是低档次的系统,该系统由CCD(摄像头)、图像采集卡、计算机三个部分组成,其结构简单,应用方便,效果也比较不错,得到的图像较清晰。目前网上基于VC开发经验的文章不少,可是关于如何在VC开发平台上使用图像采集卡的文章确没发现,笔者针对在科研开发中积累的使用图像采集卡经验,介绍如何自己是如何将采集卡集成到图像开发系统中,希望能够给目前正需要利用图像采集卡开发自己的图像处理系统的朋友有所帮助。

使用的摄像机采用台湾BENTECH INDUSTRIAL 有限公司生产的CV-155L黑白摄像机。该摄像机分辨率为752x582。图象采集卡我们采用北京中科院科技嘉公司开发的基于PCI 总线的CA-MPE 1000 黑白图象采集卡。使用图像采集卡分三步,首先安装采集卡的驱动程序,并将虚拟驱动文件VxD.vxd拷贝到Windows的SYSTEM目录下;这时候就可以进入开发状态了,进入VC开发平台,生成新的项目,由于生产厂家为图像采集卡提供了以mpew32.dll、mpew32.lib命名的库文件,库中提供了初始硬件、采集图像等函数,为使用这些函数,在新项目上连接该动态库;最后一步就是采集图像并显示处理了,这一步要设置系统调色板,因为采集卡提供的是裸图形式,既纯图像数据,没有图像的规格和调色板信息,这些需要开发者自己规定实现,下面是实现的部分代码:

CTestView::CTestView()

{

W32_Init_MPE1000();//初始化采集卡

W32_Modify_Contrast(50);//下面的函数是为了对采集卡进行预设置

W32_Modify_Brightness(45);//设置亮度

W32_Set_HP_Value(945);//设置水平采集点数

wCurrent_Frame = 1;//当前帧为1,获取的图像就是从这帧取得的

// 设置采集信号源,仅对MPE1000有效

W32_Set_Input_Source(1);

W32_CACardParam(AD_SETHPFREQ,hpGrabFreq);

W32_Set_PAL_Range(1250, 1024);//设置水平采集范围

W32_Set_VGA_Mode ( 1 );

wGrabWinX1 = 0; // 采集窗口的左上角的坐标

wGrabWinY1 = 0;

firstTime=TRUE;

bGrabMode = FRAME;

bZipMode = ZIPPLE;

/

lpDib=NULL;//存放获取的图像数据

}

CTestView::~CTestView()

{

W32_Close_MPE1000();//关闭采集卡

}

////显示采集的图象,双击鼠标采集停止

void CTestView::OnGraboneframe()

{

// TODO: Add your command handler code here

wCurrent_Frame = 1;

// 设置采集目标为内存

W32_CACardParam (AD_SETGRABDEST, CA_GRABMEM);

// 启动采集

if (lpDib != NULL)

{

GlobalUnlock( hglbDIB );

GlobalFree( hglbDIB );

}

// 分配内存

hglbDIB=GlobalAlloc(GHND, (DWORD)wImgWidth*(DWORD)wImgHeight );

lpDib = (BYTE *)GlobalLock( hglbDIB );

hdc = GetDC()->GetSafeHdc( ) ;

if(lpDib != NULL)

{

cxDib = wImgWidth;

cyDib = wImgHeight;

SetLogicPal( hdc, cxDib, cyDib, 8 );

SetStretchBltMode (hdc, COLORONCOLOR) ;

bGrabMark = TRUE;

while (bGrabMark == TRUE)

{

if(msg.message==WM_LBUTTONDBLCLK)

bGrabMark = FALSE;

W32_ReadXMS2Buf (wCurrent_Frame,lpDib) ;

SetDIBitsToDevice (hdc, 0, 0, cxDib, cyDib, 0, 0,

0, cyDib, (LPSTR) lpDib,

bmi,

DIB_RGB_COLORS) ;

}

// 停止采集

W32_CAStopCapture();

::ReleaseDC( GetSafeHwnd(), hdc );

return ;

}

////将下面这个函数添加在视图类的CTestView::OnSize()函数中,就可以对系统的调色板进行设置。

void WINAPI InitLogicPal( HDC hdc , short width, short height, WORD bitCount )

{

int j, i;

short cxDib, cyDib;

LOGPALETTE * pLogPal;

j=256 ;

if ((pLogPal=(LOGPALETTE *)malloc(sizeof(LOGPALETTE) + (j*sizeof(PALETTEENTRY)))) == NULL)

return ;

pLogPal->palVersion=0x300;

pLogPal->palNumEntries=j;

for (i=0;i pLogPal->palPalEntry[i].peRed = i ;

pLogPal->palPalEntry[i].peGreen = i ;

pLogPal->palPalEntry[i].peBlue = i ;

pLogPal->palPalEntry[i].peFlags = 0;

}

hPal = ::CreatePalette(pLogPal);

delete pLogPal;

::SelectPalette(hdc,hPal,0);

::RealizePalette(hdc);

cxDib = width; cyDib = height;

if ( (bmi = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + j*sizeof(RGBQUAD))) == NULL )

return ;

//bmi为全局变量,用于显示图像时用

bmi->bmiHeader.biSize = 40;

bmi->bmiHeader.biWidth = cxDib;

bmi->bmiHeader.biHeight = cyDib;

bmi->bmiHeader.biPlanes = 1 ;

bmi->bmiHeader.biBitCount = bitCount ;

bmi->bmiHeader.biCompression = 0 ;

bmi->bmiHeader.biSizeImage = 0 ;

bmi->bmiHeader.biXPelsPerMeter = 0;

bmi->bmiHeader.biYPelsPerMeter = 0;

bmi->bmiHeader.biClrUsed = 0;

bmi->bmiHeader.biClrImportant = 0;

for (i=0;i bmi->bmiColors[i].rgbBlue = i ;

bmi->bmiColors[i].rgbGreen = i ;

bmi->bmiColors[i].rgbRed = i ;

bmi->bmiColors[i].rgbReserved = 0 ;

}

}

视频"画中画"技术

"画中画"这个概念类似与彩色电视机"画中画",就是在一幅大的图像内显示另外一幅内容不同的小的图像,小图像的尺寸大小一般地说为大图像尺寸的1/4或1/9,显示位置在大图像的右上角。这种技术不仅在电视技术中,在可视电话系统也可以发现这种技术的身影,它们都是依靠硬件来实现的,但是如何在VC开发平台上用编程语言来将该功能添加到自己开发的视频监控软件,为使用者提供更大的信息量呢?也许读者最容易想到的是首先显示大图像,然后再在一个固定位置画第二幅小图像,这种技术技术如果对于静止图像当然没有问题,但是对于视频流,由于每一秒钟需要画25帧,即25幅图像,这样一来计算机需要不停的画不停的擦除,会给用户以闪烁的感觉,如何解决这个问题呢?有的参考书上将大小图像分快显示,这种方法要将待显示的图像数据与显示位置的关系对应起来,容易出错不说,而且麻烦,且速度慢,为此,我对该方法进行了改进,得到了满意的效果。实现的代码如下:

void pictureinpicture( )

{

………………………..

CBitmap bitmap,*oldmap;

pData1=(BYTE*)new char[biWidth*biHeight *3];//biWidth和biHeight为视频采集卡获取//的图像尺寸。

Read(pData1,bih.biWidth*bih.biHeight *3);//该函数从采集卡中获取数据

CClientDC dc(this);

m_pBMI1= new BITMAPINFO;//自定义的BMP文件信息结构,用于后面的图像显示

m_pBMI1->bmiHeader.biBitCount=24;

m_pBMI1->bmiHeader.biClrImportant=0;

m_pBMI1->bmiHeader.biClrUsed=0;

m_pBMI1->bmiHeader.biCompression=0;

m_pBMI1->bmiHeader.biHeight=biHeight;

m_pBMI1->bmiHeader.biPlanes=1;

m_pBMI1->bmiHeader.biSize=40;

m_pBMI1->bmiHeader.biSizeImage=WIDTHBYTES(biWidth*8)*biHeight*3;

m_pBMI1->bmiHeader.biWidth=biWidth;

m_pBMI1->bmiHeader.biXPelsPerMeter=0;

m_pBMI1->bmiHeader.biYPelsPerMeter=0;

////////////////////////////////////////////////////////////////////////

pData2=(BYTE*)new char[biWidth1*biHeight1 *3];//申请存放小图像的缓冲区

Read(pData2,biWidth1*biHeight1 *3);////向该缓冲区读数据

m_pBMI2= new BITMAPINFO;

m_pBMI2->bmiHeader.biBitCount=24;

m_pBMI2->bmiHeader.biClrImportant=0;

m_pBMI2->bmiHeader.biClrUsed=0;

m_pBMI2->bmiHeader.biCompression=0;

m_pBMI2->bmiHeader.biHeight=biHeight1;

m_pBMI2->bmiHeader.biPlanes=1;

m_pBMI2->bmiHeader.biSize=40;

m_pBMI2->bmiHeader.biSizeImage=WIDTHBYTES(biWidth1*8)*biHeight1*3;

m_pBMI2->bmiHeader.biWidth=biWidth1;

m_pBMI2->bmiHeader.biXPelsPerMeter=0;

m_pBMI2->bmiHeader.biYPelsPerMeter=0;

//下面实现画中画的显示

CDC MemDc;

MemDc.CreateCompatibleDC(&dc);

bitmap.CreateCompatibleBitmap(&dc,biWidth,biHeight);

oldmap=MemDc.SelectObject(&bitmap);

::StretchDIBits(MemDc.m_hDC,0,0,biWidth,biHeight,0,0,—biWidth,biHeight,pData1,m_pBMI1,DIB_RGB_COLORS,SRCCOPY);//首先将大图像画在内寸上下文中

::StretchDIBits(MemDc.m_hDC,20,20,biWidth1,biHeight1,_

0,0,biWidth1,biHeight1,pData2,m_pBMI2,DIB_RGB_COLORS,SRCCOPY);//再将小图像画在内寸上下文中

::StretchBlt(dc.m_hDC,0,0,bih.biWidth,bih.biHeight,_

MemDc.m_hDC,0,0,bih.biWidth,bih.biHeight,SRCCOPY);//将结果显示在屏幕上。

MemDc.SelectObject(oldmap);

delete pData1;

delete m_pBMI1;

delete pData2;

delete m_pBMI2;

}

更多计算机与外设信息请关注21ic计算机与外设频道

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭