调用AForge.video.DirectShow免费实现摄像头采集和上下左右镜像功能

By admin at 20 天前 • 1人收藏 • 246人看过

这次我们使用开源免费AForge.video.DirectShow实现摄像头采集和上下左右镜像功能


前面我分享了一个收费的sharpCamera.dll程序集实现此功能, 它是个收费控件, 虽然费用也不高. 但是我们能先用免费的就不用收费的原则 , 下面来探讨下AForge的使用方法.


二楼有写好的AForge封装库下载


和sharpCamera那个类似, AForge也是异步使用picturebox来实现


image.png


import win.ui;
/*DSG{{*/
mainForm = win.form(text="aardio工程2";right=959;bottom=564)
mainForm.add(
button={cls="button";text="start";left=307;top=527;right=418;bottom=553;db=1;dl=1;z=2};
button2={cls="button";text="stop";left=430;top=527;right=542;bottom=553;db=1;dl=1;dr=1;z=3};
button3={cls="button";text="flip";left=553;top=527;right=669;bottom=553;db=1;dr=1;z=4};
combobox={cls="combobox";left=53;top=527;right=286;bottom=553;db=1;dl=1;edge=1;items={};mode="dropdownlist";z=5};
custom={cls="custom";text="自定义控件";left=0;top=0;right=960;bottom=520;bgcolor=12639424;db=1;dl=1;dr=1;dt=1;z=1}
)
/*}}*/

import dotNet
import System.Drawing;
import System.Windows.Forms;
var pictureBox1 = System.Windows.Forms.CreateEmbed("PictureBox",mainForm.custom); 
pictureBox1.BackColor = System.Drawing.Color.Black;
pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
 
 dotNet.reference({
 	"AForge" = "\res\AForge.dll";
 })
var carema = dotNet.load("AForge");
var AForgeCamera = carema.import("AForge.Video"); 
var videoDevices = AForgeCamera.DirectShow.FilterInfoCollection(AForgeCamera.DirectShow.FilterCategory.VideoInputDevice);
//默认取第一个序号的摄像头
var videoDevice = AForgeCamera.DirectShow.VideoCaptureDevice(videoDevices.Item[0].MonikerString);
//摄像头包含的可用帧率和分辨率
var videoCapabilitiesEx = videoDevice.VideoCapabilities;
for(i=0;videoCapabilitiesEx.LongLength-1;1){
	mainForm.combobox.add("分辨率: "++videoCapabilitiesEx.Item[i].FrameSize.Width++"*"++videoCapabilitiesEx.Item[i].FrameSize.Height ++ " 帧率: " ++ videoCapabilitiesEx.Item[i].FrameRate);
}
if(mainForm.combobox.count){
	mainForm.combobox.selIndex = 1;
}

var flip1 = 0;
videoDevice.NewFrame = function(sender, NewFrameEventArgs){
	var temp = NewFrameEventArgs.Frame.Clone();
    select(flip1) {
        case 0 {
             
        }
        case 1 {
            temp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipX);
        }
        case 2 {
            temp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipXY);
        }
        case 3 {
            temp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY);
        }
        else {
        }
    }
     
    if (pictureBox1.Image != null)
    {
        pictureBox1.Image.Dispose();
    }
    pictureBox1.Image = temp;
}

mainForm.button.oncommand = function(id,event){
	videoDevice.Stop();
	if(mainForm.combobox.count){
		//设定帧率和分辨率
		videoDevice.DesiredFrameRate = videoCapabilitiesEx.Item[mainForm.combobox.selIndex-1].FrameRate;
		videoDevice.DesiredFrameSize = videoCapabilitiesEx.Item[mainForm.combobox.selIndex-1].FrameSize;
		videoDevice.DesiredSnapshotSize = videoCapabilitiesEx.Item[mainForm.combobox.selIndex-1].FrameSize;
		videoDevice.Start();
	}
}

mainForm.button2.oncommand = function(id,event){
	videoDevice.Stop();
}

mainForm.button3.oncommand = function(id,event){
	select(flip1) {
        case 0 {
            flip1=1;
        }
        case 1 {
            flip1=2;
        }
        case 2 {
            flip1=3;
        }
        case 3 {
            flip1=0;
        }
        else {
        }
    }
}

mainForm.onClose = function(hwnd,message,wParam,lParam){
    videoDevice.Stop();
}

mainForm.show();
return win.loopMessage();


完整测试工程如下:

aardio工程2.zip


3 个回复 | 最后更新于 17 天前
18 天前   #1

简单封装了个AForgeVideo摄像头库:

image.png

//AForge摄像头库
import dotNet
import System.Drawing;
import System.Windows.Forms;

class AForgeVideo{
	ctor( winform ){
		this.pictureBox = ..System.Windows.Forms.CreateEmbed("PictureBox",winform); 
		this.pictureBox.BackColor = ..System.Drawing.Color.Black;
		this.pictureBox.SizeMode = ..System.Windows.Forms.PictureBoxSizeMode.StretchImage;
		this.carema = ..dotNet.load("\res\AForge.dll");
		this.AForgeCamera = this.carema.import("AForge.Video");
		this.flip = 0;
		this.videoDevice = null;
		..table.gc(this,"stop");
	};
	
	getNameList = function(){
		var videoDevices = this.AForgeCamera.DirectShow.FilterInfoCollection(this.AForgeCamera.DirectShow.FilterCategory.VideoInputDevice);
		var retTab = {};
		if(videoDevices.Count>0){
			for(i=0;videoDevices.Count-1;1){
				//压入摄像头设备号名称列表	
				..table.push(retTab , videoDevices.Item[i].MonikerString);
			}
			return retTab; 
		}
		return null;
	}
	
	getVideoCapabilitiesList = function(deviceName){
		if(deviceName!=null){
			var videoDevice = this.AForgeCamera.DirectShow.VideoCaptureDevice(deviceName);
			var videoCapabilitiesEx = videoDevice.VideoCapabilities;
			var retTab = {};
			if(videoCapabilitiesEx.LongLength>0){
				for(i=0;videoCapabilitiesEx.LongLength-1;1){
					..table.push(retTab,{
						["Width"] = videoCapabilitiesEx.Item[i].FrameSize.Width,
						["Height"] = videoCapabilitiesEx.Item[i].FrameSize.Height,
						["FrameRate"] = videoCapabilitiesEx.Item[i].FrameRate,
					});
				}
				return retTab;
			}
			return null; 
		}
		return null;
	}
	
	start = function(DeviceIndex=1,index=1){
		if(this.videoDevice){
			this.videoDevice.Stop();
		}
		
		var namelist = this.getNameList();
		if(DeviceIndex <= #namelist){
			name = namelist[DeviceIndex];
		}else {
			//超出摄像头数量,不开启
			return false;
		}	
		//设定帧率和分辨率
		var VideoCapabilities = this.getVideoCapabilitiesList(name);
		this.videoDevice = this.AForgeCamera.DirectShow.VideoCaptureDevice(name);
		
		if(VideoCapabilities!=null){
			if(index>#VideoCapabilities){
				index = 1;
			}
			this.videoDevice.DesiredFrameRate = VideoCapabilities[index].FrameRate;
			this.videoDevice.DesiredFrameSize = ..System.Drawing.Size(VideoCapabilities[index].Width,VideoCapabilities[index].Height);
			this.videoDevice.DesiredSnapshotSize = ..System.Drawing.Size(VideoCapabilities[index].Width,VideoCapabilities[index].Height);
		}
		
		this.videoDevice.NewFrame = function(sender, NewFrameEventArgs){
			var temp = NewFrameEventArgs.Frame.Clone();
    		select(this.flip) {
        		case 0 {
             		
        		}
        		case 1 {
            		temp.RotateFlip(..System.Drawing.RotateFlipType.RotateNoneFlipX);
        		}
        		case 2 {
            		temp.RotateFlip(..System.Drawing.RotateFlipType.RotateNoneFlipXY);
        		}
        		case 3 {
            		temp.RotateFlip(..System.Drawing.RotateFlipType.RotateNoneFlipY);
        		}
        		else {
        		}
    		}
     		
    		if (this.pictureBox.Image != null)
    		{
        		this.pictureBox.Image.Dispose();
    		}
    		this.pictureBox.Image = temp;
		}
		this.videoDevice.Start();
		return true;
	}
	
	stop = function(){
		if(this.videoDevice){
			this.videoDevice.Stop();
			this.videoDevice = null;
		}
	}
	
	flipLoop = function(){
		select(this.flip) {
        	case 0 {
            	this.flip=1;
        	}
        	case 1 {
            	this.flip=2;
        	}
        	case 2 {
            	this.flip=3;
        	}
        	case 3 {
            	this.flip=0;
        	}
        	else {
        	}
    	}
	}
}

/**intellisense()
AForgeVideo = AForge摄像头库
AForgeVideo(.(winform) = 创建 摄像头 界面
AForgeVideo() = !AVideo.
end intellisense**/

/**intellisense(!AVideo)
getNameList() = 获取摄像头设备硬件DeviceName名称列表
getVideoCapabilitiesList(.(DeviceName) = 获取指定设备的 分辨率和帧率 列表,如果不存在那么返回 null
start(.(DeviceIndex,CapabilitiesIndex) = 开启摄像头\n DeviceIndex:设备序号 , CapabilitiesIndex:分辨率和帧率表序号
stop() = 关闭摄像头
flipLoop() = 循环镜像图像,调用一次改变一次镜像方向
end intellisense**/

使用的时候:

import win.ui;
/*DSG{{*/
mainForm = win.form(text="aardio工程2";right=1209;bottom=556)
mainForm.add(
button={cls="button";text="start";left=16;top=519;right=127;bottom=545;db=1;dl=1;z=2};
button2={cls="button";text="flip";left=142;top=519;right=254;bottom=545;db=1;dl=1;z=3};
button3={cls="button";text="stop";left=265;top=519;right=381;bottom=545;db=1;dl=1;z=4};
button4={cls="button";text="start";left=833;top=518;right=944;bottom=544;db=1;dr=1;z=6};
button5={cls="button";text="flip";left=959;top=518;right=1071;bottom=544;db=1;dr=1;z=7};
button6={cls="button";text="stop";left=1082;top=518;right=1198;bottom=544;db=1;dr=1;z=8};
custom={cls="custom";text="自定义控件";left=0;top=0;right=601;bottom=496;bgcolor=12639424;db=1;dl=1;dr=0.5;dt=1;z=1};
custom2={cls="custom";text="自定义控件";left=609;top=0;right=1210;bottom=496;bgcolor=12639424;db=1;dl=0.5;dr=1;dt=1;z=5}
)
/*}}*/

import AForgeVideo;
var video = AForgeVideo(mainForm.custom);

mainForm.button.oncommand = function(id,event){
	//默认开启序号1摄像头,分辨率为序号1的分辨率和帧率
	video.start();
}

mainForm.button2.oncommand = function(id,event){
	//摄像头1镜像
	video.flipLoop();
}

mainForm.button3.oncommand = function(id,event){
	//摄像头1停止
	video.stop();
}

//定义2号摄像头
var video2 = AForgeVideo(mainForm.custom2);
mainForm.button4.oncommand = function(id,event){
	//开启序号2摄像头,分辨率为序号1的分辨率和帧率
	video2.start(2);
}

mainForm.button5.oncommand = function(id,event){
	//摄像头2镜像
	video2.flipLoop();
}

mainForm.button6.oncommand = function(id,event){
	//摄像头2停止
	video2.stop();
}

mainForm.show();
return win.loopMessage();


完整示例工程和库代码如下:

AForge.zip


17 天前   #2

有没有注意到监控有延迟吗?

17 天前   #3

回复#2 @aunox :

就是用了很多中摄像头ocx和dll控件后, 才发现这种方式延迟小. 灵活性高.

很多国外的ocx里面包含了杂七杂八的功能, 导致有些usb摄像头延迟非常大, 或者出现水纹 , 国内的摄像头ocx好很多, 但是收费也不便宜 , 这种.net的控件只专注于采集图像, 然后输出给你, 至于怎么处理是让你自己考虑, 所以少了很多环节 , 

对比我之前所发的所有关于摄像头的 , 目前我测试这种方式貌似最好.

如果你摄像头延迟大, 你用顶楼那个程序测试下, 里面可以选[ 分辨率和帧率 ] 理论上帧率高延迟就小, 如果你摄像头不支持高帧率, 那就没办法了.


备注:

界面里面所示的[ 分辨率和帧率 ] 是从usb设备上通信获得的, 不是随意输入的, 是硬件所支持的硬指数.

登录后方可回帖

登 录
信息栏
公告:
个人博客
专注分享
可在分享中适当提问
谢绝纯提问
否则不再提醒一律
删帖
谢谢合作!



本站域名:HtmLayout.Cn
aardio可以快速开发上位机,本站主要记录了学习过程中遇到的问题和解决办法及aardio代码分享

这里主要专注于aardio学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.

Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
空间赞助:才仁机械
Loading...