Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Picturebox上显示从相机检索的位图的实验_C#_Opencv_Bitmap_Camera_Picturebox - Fatal编程技术网

C# 在Picturebox上显示从相机检索的位图的实验

C# 在Picturebox上显示从相机检索的位图的实验,c#,opencv,bitmap,camera,picturebox,C#,Opencv,Bitmap,Camera,Picturebox,在我的代码中,我使用指向非托管对象的指针从相机检索帧,对其进行一些计算,然后将其显示在picturebox控件上。 在我进一步介绍这个应用程序的所有细节之前,我想确保这个过程的基本代码是好的。 我特别想: -尽量减少执行时间,避免不必要的操作,例如 复制的图像比需要的多。我只想保留必要的东西 操作 -了解每帧计算过程中的延迟是否会对图像的显示方式产生不利影响(即,如果未按我的预期打印),或者跳过某些图像 -防止更严重的错误,例如由于内存或线程管理或图像显示引起的错误。 为此,我设置了一些实验性的

在我的代码中,我使用指向非托管对象的指针从相机检索帧,对其进行一些计算,然后将其显示在picturebox控件上。
在我进一步介绍这个应用程序的所有细节之前,我想确保这个过程的基本代码是好的。 我特别想:
-尽量减少执行时间,避免不必要的操作,例如 复制的图像比需要的多。我只想保留必要的东西 操作
-了解每帧计算过程中的延迟是否会对图像的显示方式产生不利影响(即,如果未按我的预期打印),或者跳过某些图像
-防止更严重的错误,例如由于内存或线程管理或图像显示引起的错误。
为此,我设置了一些实验性的代码行(如下),但我无法解释我发现的结果。如果你有OpenCv的可执行文件,你可以自己试试

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;

public partial class FormX : Form
{
private delegate void setImageCallback();
Bitmap _bmp;
Bitmap _bmp_draw;
bool _exit;
double _x;
IntPtr _ImgBuffer;

bool buffercopy;
bool copyBitmap;
bool refresh;

public FormX()
{
    InitializeComponent();
    _x = 10.1;

    // set experimemental parameters
    buffercopy = false;
    copyBitmap = false;
    refresh = true;
}

private void buttonStart_Click(object sender, EventArgs e)
{
    Thread camThread = new Thread(new ThreadStart(Cycle));
    camThread.Start();
}

private void buttonStop_Click(object sender, EventArgs e)
{
    _exit = true;
}

private void Cycle()
{
    _ImgBuffer = IntPtr.Zero;
    _exit = false;

    IntPtr vcap = cvCreateCameraCapture(0);
    while (!_exit)
    {
        IntPtr frame = cvQueryFrame(vcap);

        if (buffercopy)
        {
            UnmanageCopy(frame);
            _bmp = SharedBitmap(_ImgBuffer);
        }
        else
        { _bmp = SharedBitmap(frame); }

        // make calculations
        int N = 1000000; /*1000000*/
        for (int i = 0; i < N; i++)
            _x = Math.Sin(0.999999 * _x);

        ShowFrame();
    }

    cvReleaseImage(ref _ImgBuffer);
    cvReleaseCapture(ref vcap);
}


private void ShowFrame()
{
    if (pbCam.InvokeRequired)
    {
        this.Invoke(new setImageCallback(ShowFrame));
    }
    else
    {
        Pen RectangleDtPen = new Pen(Color.Azure, 3);

        if (copyBitmap)
        {
            if (_bmp_draw != null) _bmp_draw.Dispose();
            //_bmp_draw = new Bitmap(_bmp); // deep copy
            _bmp_draw = _bmp.Clone(new Rectangle(0, 0, _bmp.Width, _bmp.Height), _bmp.PixelFormat);
        }
        else
        {
            _bmp_draw = _bmp;  // add reference to the same object
        }

        Graphics g = Graphics.FromImage(_bmp_draw);
        String drawString = _x.ToString();
        Font drawFont = new Font("Arial", 56);
        SolidBrush drawBrush = new SolidBrush(Color.Red);
        PointF drawPoint = new PointF(10.0F, 10.0F);
        g.DrawString(drawString, drawFont, drawBrush, drawPoint);
        drawPoint = new PointF(10.0F, 300.0F);
        g.DrawString(drawString, drawFont, drawBrush, drawPoint);
        g.DrawRectangle(RectangleDtPen, 12, 12, 200, 400);
        g.Dispose();

        pbCam.Image = _bmp_draw;
        if (refresh) pbCam.Refresh();
    }
}

public void UnmanageCopy(IntPtr f)
{
    if (_ImgBuffer == IntPtr.Zero)
        _ImgBuffer = cvCloneImage(f);
    else
        cvCopy(f, _ImgBuffer, IntPtr.Zero);
}

// only works with 3 channel images from camera! (to keep code minimal)
public Bitmap SharedBitmap(IntPtr ipl)
{
    // gets unmanaged data from pointer to IplImage:
    IntPtr scan0;
    int step;
    Size size;
    OpenCvCall.cvGetRawData(ipl, out scan0, out step, out size);
    return new Bitmap(size.Width, size.Height, step, PixelFormat.Format24bppRgb, scan0);
}

// based on older version of OpenCv. Change dll name if different
[DllImport( "opencv_highgui246", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr cvCreateCameraCapture(int index);

[DllImport("opencv_highgui246", CallingConvention = CallingConvention.Cdecl)]
public static extern void cvReleaseCapture(ref IntPtr capture);

[DllImport("opencv_highgui246", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr cvQueryFrame(IntPtr capture);

[DllImport("opencv_core246", CallingConvention = CallingConvention.Cdecl)]
public static extern void cvGetRawData(IntPtr arr, out IntPtr data, out int step, out Size roiSize);

[DllImport("opencv_core246", CallingConvention = CallingConvention.Cdecl)]
public static extern void cvCopy(IntPtr src, IntPtr dst, IntPtr mask);

[DllImport("opencv_core246", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr cvCloneImage(IntPtr src);

[DllImport("opencv_core246", CallingConvention = CallingConvention.Cdecl)]
public static extern void cvReleaseImage(ref IntPtr image);
}
使用系统;
使用系统图;
使用系统、绘图、成像;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
使用系统线程;
公共部分类FormX:Form
{
私有委托void setImageCallback();
位图bmp;
位图\u bmp\u绘制;
布尔乌出口;
双x;
IntPtr_ImgBuffer;
布尔缓冲拷贝;
bool复制位图;
布尔刷新;
公共表格x(
{
初始化组件();
_x=10.1;
//设置实验参数
buffercopy=false;
copyBitmap=false;
刷新=真;
}
私有无效按钮开始单击(对象发送者,事件参数e)
{
螺纹凸轮螺纹=新螺纹(新螺纹开始(循环));
camThread.Start();
}
私有无效按钮停止单击(对象发送者,事件参数e)
{
_退出=真;
}
私有无效循环()
{
_ImgBuffer=IntPtr.Zero;
_退出=假;
IntPtr vcap=cvCreateCameraCapture(0);
while(!\u退出)
{
IntPtr帧=cvQueryFrame(vcap);
如果(缓存副本)
{
非托管拷贝(帧);
_bmp=共享的位图(_ImgBuffer);
}
其他的
{{u bmp=SharedBitmap(框架);}
//算计
整数N=1000000;/*1000000*/
对于(int i=0;i
结果[双核2 Duo T6600 2.2 GHz]:

A。buffercopy=false;copyBitmap=false;刷新=错误
这是更简单的配置。依次检索每一帧,进行操作(实际上它们基于同一帧,这里只是计算),然后将计算结果打印在图像顶部,最后显示在图片盒上。
OpenCv文档说明:

OpenCV 1.x函数cvRetrieveFrame和cv.RetrieveFrame返回图像 存储在视频捕获结构中。这是不允许的 修改或释放图像!可以使用复制帧 cvCloneImage()然后对副本执行任何操作

但这并不妨碍我们做实验。
如果计算结果不正确