如何在wpf的某个窗口中获取opencv调用摄像头获取的视频?
我现在写好了opencv调用摄像头获取视频的程序,也能在wpf中调用,就是不知道怎么把这个视频放到wpf的窗口中去?
希望会的大神们能够帮帮我!在线等!!!
兄弟,你一点分不给我不想回答
30
你还在吗?能指导指导我吗?
@soumns丶涛: 是这样的,我这里正好有一个在wpf中显示摄像头的项目。
我看了一下,具体是开了一个线程不断地获摄像头的二进制数据,然后转化为一个图片,绑定在wpf的一个Border里,这样Border里就能实时显示摄像头的图片了
@猝不及防: 我是要wpf里面调用用opencv写的视频程序,我opencv程序是写成dll,在wpf中调用的,现在我就是不知道怎么调用到wpf的控件中去
@soumns丶涛: 你这个用opencv写的东西是啥,也是wpf吗
@猝不及防: 不是 opencv写的是拍照程序
@猝不及防: 使用C++写的dll 在wpf中调用的
@猝不及防: opencv写的是调取摄像头拍照片的程序
@soumns丶涛: ....
你用wpf,那你要确定你提供的是什么....
是数据,图片,wpf还是winform...
然后才能确定是把数据嵌入wpf,还是图片嵌入wpf,还是把另一个wpf嵌入wpf,还是把winform嵌入wpf...
你知道引用dll,那你得确认这个dll提供的东西是什么啊
@soumns丶涛: 你这个程序是dll库是把,那你看看库里面能提供什么好吗
@猝不及防:
C++ dll自己写的拍照程序:
// TakePhotos.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include<opencv2/opencv.hpp>
#include<Windows.h>
using namespace cv;
extern "C" __declspec(dllexport) int TakePhotos(intptr_t hWnd)
{
IplImage *pImg = NULL;
CvCapture *cap = cvCaptureFromCAM(0);
char fileName[100];
char key;
int count = 0;
////获得动态创建窗口的句柄
//cvNamedWindow("Camera", 0);
//HWND hWnd = (HWND)cvGetWindowHandle("Camera");
////获得动态创建窗口父窗口的句柄
//HWND hParent = ::GetParent(hWnd);
while(1)
{
pImg = cvQueryFrame(cap);
//cvFlip(pImg, NULL, 1); //水平翻转图像
/*namedWindow("Camera");*/
key = cvWaitKey(30);
if(key == 27) //按ESC键退出程序
{
destroyWindow("Camera");
break;
}
if(key == 'c') //按c键拍照
{
sprintf(fileName, "F:\\pic\\Test\\%d.jpg", ++count); //生成(Picture1,2,3,4......jpg)文件名
cvSaveImage(fileName, pImg);
cvXorS(pImg, cvScalarAll(255), pImg); //将拍到的图像反色(闪一下形成拍照效果)
cvShowImage("Camera",pImg);
waitKey(200); //反色图像显示ms
}
cvShowImage("Camera",pImg);
}
cvReleaseCapture(&cap);
return 0;
}
wpf前台代码:
<Window x:Class="BS_wpf.TakePhotos_Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TakePhotos_Window" Height="300" Width="650">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Name="text_cap_num" Text="cap_num:" Grid.Column="2" Grid.Row="0"
VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5"/>
<ComboBox Name="cbo_cap_num" Grid.Column="3" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left"
Margin="5" Height="30" Width="130"/>
<WindowsFormsHost Grid.ColumnSpan="2" Grid.RowSpan="7" Height="249" HorizontalAlignment="Left"
Margin="6,6,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="308" />
</Grid>
</Grid>
</Window>
后台:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Interop;
namespace BS_wpf
{
/// <summary>
/// TakePhotos_Window.xaml 的交互逻辑
/// </summary>
public partial class TakePhotos_Window : Window
{
public TakePhotos_Window()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Take_Photos.TakePhotos(this.windowsFormsHost1.Handle);
}
}
}
就是不知道怎么让视频显示在WindowsFormsHost 中??
WindowsFormsHost 可以支持与 winform 互调用
C++ dll自己写的拍照程序:
// TakePhotos.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include<opencv2/opencv.hpp>
#include<Windows.h>
using namespace cv;
extern "C" __declspec(dllexport) int TakePhotos(intptr_t hWnd)
{
IplImage *pImg = NULL;
CvCapture *cap = cvCaptureFromCAM(0);
char fileName[100];
char key;
int count = 0;
////获得动态创建窗口的句柄
//cvNamedWindow("Camera", 0);
//HWND hWnd = (HWND)cvGetWindowHandle("Camera");
////获得动态创建窗口父窗口的句柄
//HWND hParent = ::GetParent(hWnd);
while(1)
{
pImg = cvQueryFrame(cap);
//cvFlip(pImg, NULL, 1); //水平翻转图像
/*namedWindow("Camera");*/
key = cvWaitKey(30);
if(key == 27) //按ESC键退出程序
{
destroyWindow("Camera");
break;
}
if(key == 'c') //按c键拍照
{
sprintf(fileName, "F:\\pic\\Test\\%d.jpg", ++count); //生成(Picture1,2,3,4......jpg)文件名
cvSaveImage(fileName, pImg);
cvXorS(pImg, cvScalarAll(255), pImg); //将拍到的图像反色(闪一下形成拍照效果)
cvShowImage("Camera",pImg);
waitKey(200); //反色图像显示ms
}
cvShowImage("Camera",pImg);
}
cvReleaseCapture(&cap);
return 0;
}
wpf前台代码:
<Window x:Class="BS_wpf.TakePhotos_Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TakePhotos_Window" Height="300" Width="650">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Name="text_cap_num" Text="cap_num:" Grid.Column="2" Grid.Row="0"
VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5"/>
<ComboBox Name="cbo_cap_num" Grid.Column="3" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left"
Margin="5" Height="30" Width="130"/>
<WindowsFormsHost Grid.ColumnSpan="2" Grid.RowSpan="7" Height="249" HorizontalAlignment="Left"
Margin="6,6,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="308" />
</Grid>
</Grid>
</Window>
后台:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Interop;
namespace BS_wpf
{
/// <summary>
/// TakePhotos_Window.xaml 的交互逻辑
/// </summary>
public partial class TakePhotos_Window : Window
{
public TakePhotos_Window()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Take_Photos.TakePhotos(this.windowsFormsHost1.Handle);
}
}
}
就是不知道怎么让视频显示在WindowsFormsHost 中??
@soumns丶涛: WindowsFormsHost 里可以放一个winform控件.比如一个pictureBox
@soumns丶涛: 爱莫能助,C++-->c# 不会
你FormHost了试问怎么操作Image?
正常的做法,创建wpf,nuget opencv(有这个c#版本甚至wpf版本,还有emgucv等等版本);
你这比较瞎搞,非要抄c++的demo(你上面的代码我没记错的话是书上的demo) 然后跑c#的壳,如果只是个壳又何必跑c#呢,当然你如果像以前呆过的一家公司 —— 由于c++及算法过分牛逼,界面有一堆菜鸟wpf,他们的确这么干的,wpf什么都不干,只是参与壳。
对 就是你说的这么一回事 那你会把这个视频放到wpf窗口中吗?
@soumns丶涛: 不是给你说了方法得嘛。你先创建winForm或者wpf,然后去nuget,那么直接就是c#版本了,你需要把上面的代码,小小调整一下就OK了,最终拿到Image —— 这玩意儿可以说在c#中你爱怎么显示就怎么显示。这才是c#正干的事。c#版本的opencv函数几乎一致,所以不必担心,我去年还用来着弄验证码识别,基本上照着c++的函数一路抄过去就行了。
@花飘水流兮: 像学习这些wpf之类的,有什么书籍,网站的推荐一下没?
@soumns丶涛:
你理解水平凑合的话基本不用什么教程。
用用就知道了,看看其视图体系,了解一下基本概念就行了(用到特别东西查一查就行了)。
和其他后起视图设计类似,和传统MFC或者winForm等主要区别就在于多了布局(实际上winForm后来也有这种玩意儿)比如QT、Android之类,但这个东西设计得更加简单方便。—— 就是先去用他一些常用布局,比如Gird,StackPanel等(这两个频率最高,在其他QT和Android中也有类似得东西)。
还有就是为了方便和规范代码编辑,后起视图还流行一个东西叫binding,他也属于这种,详见他的一个INotityPropertyChanged(貌似叫这个),我一般不用 —— 不灵活,实际对我代码更多。总而言之各种视图设计往现在的网页模式走拢,网页模式各主流模块也在mv中逐渐分离得更加清晰。