Мерцание на дисплее видео камеры, почему? - PullRequest
1 голос
/ 28 февраля 2012

На дисплее видеокамеры мерцает изображение, хотя я (кажется, я) отключил стирание фона.Почему?

enter image description here

Даже текст, отображаемый над видеопрезентацией, мигает.

Полный код в Bitbucket .

Возможно, наиболее релевантный код, гизмо для отображения видео:

class ImageDisplay:
    public gizmo::SubGizmo
{
typedef gizmo::SubGizmo Base;
private:
    winapi::graphics::ColorDib      dib_;

protected:
    void onPaint( raw::DcHandle const dc ) CPP_IS_OVERRIDE
    {
        dib_.renderOn( dc );
    }

    bool onWmEraseBkgnd( raw::DcHandle const dc )
    {
        CPP_DECLARE_UNUSED( dc );
        return true;        // Just say it's done, so it won't be done again.
    }

    void onWmPaint() CPP_IS_OVERRIDE
    {
        callOnPaint();
    }

    virtual raw::LResult dispatchWm(
        raw::UInt const     messageId,
        raw::WParam const   wParam,
        raw::LParam const   lParam
        )
    {
        CPP_DUMMY_USE_OF( wParam );  CPP_DUMMY_USE_OF( lParam );

        typedef ImageDisplay W;
        switch( messageId )
        {
        case WM_ERASEBKGND:
            return FORWARD_WM_TO( this, W::onWmEraseBkgnd, WM_ERASEBKGND, wParam, lParam );
        }

        return Base::dispatchWm( messageId, wParam, lParam );
    }

public:
    void setImage( cvapi::ImageRef const newImage )
    {
        dib_ = win_cv::dibFrom( newImage );
        setExtent( newImage.extent() );
    }

    ImageDisplay(
        Gizmo&                  parent,
        int const               x,
        int const               y,
        cvapi::ImageRef const&  pic
        )
        : Base( parent, x, y, pic.width(), pic.height() )
        , dib_( win_cv::dibFrom( pic ) )
    {}
};

Основной код из потока видео производителя:

void imageProducer( 
    wstring const&              namePattern,
    PutFunction const           putResult,
    Thread::Control const&      threadControl
    )
{
    assert( !!putResult );

    cv::VideoCapture cap( 0 );  // Open the default camera.
    hopefully( cap.isOpened() )
        || throwX( "cam::imageProducer: VideoCapture::<init> failed" );

    for(;;)
    {
        cv::Mat frame;

        if( threadControl.exitIsRequested() ) { return; }
        cap >> frame;           // Get a new frame from camera.

        if( threadControl.exitIsRequested() ) { return; }
        putResult( frame );
    }
}

Функция putResult просто вызывает SendMessage Windows, который синхронизируется с потоком отображения.

Я не вижу, как удается проникнуть мерцанию?


EDIT : я нашел исправление, а именнодобавив WS_CLIPCHILDREN к главному окну и используя RedrawWindow, чтобы вызвать немедленное перерисовывание элемента управления (дочернее окно).Большая загадка, почему это работает.Большая загадка: без применения RedrawWindow, WS_CLIPCHILDREN вызывает чрезвычайную медленность, например, 1 кадр каждые 20 секунд?

РЕДАКТИРОВАТЬ 2 : это не длилось долго.: - (

РЕДАКТИРОВАТЬ 3 : * РЕШЕНО *. И mea culpa . Все это мерцание было вызвано неправильным вызовом InvalidateRect, в коде главного окна. Я, вероятно, положил его туда только для проверки, и забыл удалить его. Argh!

1 Ответ

2 голосов
/ 29 февраля 2012

Mea culpa . Все это мерцание было вызвано неправильным вызовом Windows & rsquo; InvalidateRect, в коде главного окна. Я, вероятно, положил этот вызов там, чтобы проверить вещи, и забыл удалить его. Argh!

Обучение:

Не вините & ldquo; систему & rdquo; (здесь Windows API, но также компилятор и т. д.), прежде чем вы проверите абсолютно все в своем собственном коде. Это как грязные отпечатки пальцев на ваших очках. Вы никогда не кладете пальцы на очки, и все же появляются эти отпечатки пальцев; то же самое с загадочными нежелательными утверждениями в коде.

...