2014-04-28 2 views
4

비디오 캡처 카드 (AverMedia Game Broadcaster HD)에 연결된 GoPro Hero 3+ (검정색)가 있습니다. 간단히 OpenCV에서 비디오 스트림을 얻고 싶습니다. Logitech 웹캠에는 문제가 없습니다. 사용 된 코드는 아래와 같습니다. OpenCV의가 ("캠 확인")을 VideoCapture를 열 수 있지만 프레임 (단지 회색 화면과 출력을 읽을 수 없습니다 : 다음은 GoPro의와 OpenCV 및 GoPro - VideoCapture 스트림의 빈 프레임

VideoCapture cap; 
cap.open(0); 

waitKey(300); 

//cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280); 
//cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720); 

if (cap.isOpened()){ 
    cout << "Cam identified" << endl; 
} 

namedWindow("dst", 1); 

while (1){ 

Mat frame; 

if (!cap.read(frame)) { 
    std::cout << "Unable to read frame from video stream" << std::endl; 
    continue; 
} 

imshow("dst", frame); 

[...] 

} 

발생 "비디오에서 프레임을 읽을 수 없습니다 흐름"). 나는 또한 이것을 frame.empty();로 확인했다.

Unity가 어떤 문제없이 GoPro 스트림으로 WebCamTexture를 열기 때문에 비디오 캡처 카드가 올바르게 작동한다는 것을 알고 있습니다. OpenCv에서 코덱 문제를 읽었으므로 이미 FFMPEG 지원으로 OpenCV를 컴파일하려고했습니다. 이제는 GoPro의 기록 된 MP4 동영상을 표시 할 수 있지만 스트림은 여전히 ​​작동하지 않습니다.

내가 OpenCV의 2.48, 윈도우 7 및 Visual Studio를 사용하여 2013 년


편집 : 나는 스트리밍하려고 같은 문제를 했어

struct ctx 
{ 
uint8_t* pixeldata; 
std::mutex imagemutex; 
}; 

static void display(void *data, void *id); 
static void unlock(void *data, void *id, void *const *p_pixels); 
static void *lock(void *data, void **p_pixels); 

struct ctx ctx; 

libvlc_instance_t *inst; 
libvlc_media_player_t *mp; 
libvlc_media_t *m; 

int main(int argc, char* argv[]) 
{ 
    ctx.pixeldata = new uint8_t[1280 * 720 * 3]; 

    char const *vlc_argv[] = 
    { 
     "-vvv", 
     "--no-audio", /* skip any audio track */ 
     "--no-xlib", /* tell VLC to not use Xlib */ 
    }; 

    int vlc_argc = sizeof(vlc_argv)/sizeof(*vlc_argv); 
    inst = libvlc_new(vlc_argc, vlc_argv); 

    const char *options[] = 
    { 
     ":dshow-vdev=AVerMedia HD Capture", 
     ":dshow-adev=none", 
     //":dshow-size=1280x720", 
     ":dshow-fps=24", 
     ":dshow-chroma=YUY2", 
     ":dshow-video-input=1", 
     ":dshow-video-output=1", 
     ":dshow-aspect-ratio=16\:9", 
     ":live-caching=80", 
     NULL 
    }; 

    m = libvlc_media_new_location(inst, "dshow://"); 
    for (const char **opt = options; *opt; opt++) 
     libvlc_media_add_option(m, *opt); 

    mp = libvlc_media_player_new_from_media(m); 
    libvlc_media_release(m); 
    libvlc_video_set_callbacks(mp, lock, unlock, display, &ctx); 
    libvlc_video_set_format(mp, "RV24", 1280, 720, 1280 * 3); 
    libvlc_media_player_play(mp); 

    namedWindow("all", 1); 

    Mat frame(720, 1280, CV_8UC3); 

    while (1){ 

     ctx.imagemutex.lock(); 
     memcpy(gesamt.data, ctx.pixeldata, 1280 * 720 * sizeof(uint8_t) * 3); 
     ctx.imagemutex.unlock(); 

     imshow("all", gesamt); 

     if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop 
     { 
      cout << "esc key is pressed by user" << endl; 
      break; 
     } 

    } 

    libvlc_media_player_stop(mp); 
    libvlc_media_player_release(mp); 
    libvlc_release(inst); 
    delete[] ctx.pixeldata; 

    return 0; 
} 

void display(void *data, void *id){ 
    (void)data; 
    assert(id == NULL); 
} 

void unlock(void *data, void *id, void *const *p_pixels){ 
    struct ctx *ctx = (struct ctx*)data; 
    ctx->imagemutex.unlock(); 
    assert(id == NULL); 
} 

void *lock(void *data, void **p_pixels){ 
    struct ctx *ctx = (struct ctx*)data; 
    ctx->imagemutex.lock(); 
    *p_pixels = ctx->pixeldata; 
    return NULL; 
} 

답변

1

: 여기 libVLC 솔루션의 코드는 Avermedia 캡처 카드를 통해 소니 액션 캠. 한 가지 빠른 해결 방법은 캡처 카드 출력을 웹캠처럼 보이게하는 DVDrive를 사용하는 것입니다. 이 문제를 해결 방법으로 사용하여 성공했습니다.

+0

감사합니다. 당신 말이 맞아요. DVDriver로 작동합니다. 내가 발견 한 또 다른 해결 방법은 libVLC의 directshow 기능을 사용하는 것입니다. openCV 프레임 워크 만 사용하는 솔루션을 아는 것이 여전히 좋을 것입니다. – Novatar

+0

libVLC는 좋은 팁입니다. 작동 시키려면 무엇이든지 복잡합니까? 나는 DVDrive가 고해상도에서 CPU 사이클의 적당한 덩어리를 차지하면서 아마 그것을 제공 할 것이다. – user9294

+0

알아낼 시간이 좀 남았습니다. 위 코드에서 내 코드를 볼 수 있습니다. 가장 큰 문제는 비디오 형식 설정과 opencv :: Mat에 대한 올바른 변환이었습니다. 내 첫 번째 솔루션에서 "libvlc_video_set_format (mp,"YUY2 ", 1280, 720, 1280 * 2);" 그것이 꾸러미이기 때문에 변환하는 것은 어려웠다. 첫 번째와 세 번째 바이트는 첫 번째와 두 번째 픽셀의 Y 값입니다. 두 번째 및 네 번째 바이트는 두 픽셀의 Cb 및 Cr 값입니다. 나중에 변환이 set_format 명령에서 YUY2 대신 RV24를 선택하여 직접 수행 될 수 있음을 알게되었습니다. – Novatar