2016-11-06 4 views
2

Я работаю над созданием видео с OpenCV на C++. Я попытался передать изображение после обработки из OpenCV в именованный канал с конечной целью переиздания потока с использованием веб-сервера либо с VLC, либо с сервера NodeJS.OpenCV to ffplay from named pipe (fifo)

Где я застрял в том, что выход из OpenCV, похоже, не обрабатывается правильно. У видео всегда есть артефакты, хотя это должно быть необработанное видео.

enter image description here

int main(int argc, char** argv) 
{ 

    VideoCapture camera(argv[1]); 

    float fps = 15; 

    // VLC raw video 
    printf("Run command:\n\ncat /tmp/myfifo | cvlc --demux=rawvideo --rawvid-fps=%4.2f --rawvid-width=%.0f --rawvid-height=%.0f --rawvid-chroma=RV24 - --sout \"#transcode{vcodec=h264,vb=200,fps=30,width=320,height=240}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:8081/stream.flv}\"" 
     ,fps 
     ,camera.get(CV_CAP_PROP_FRAME_WIDTH) 
     ,camera.get(CV_CAP_PROP_FRAME_HEIGHT) 
     ); 


    // ffplay raw video 
    printf("Run command:\n\ncat /tmp/myfifo | ffplay -f rawvideo -pixel_format bgr24 -video_size %.0fx%.0f -framerate %4.2f -i pipe:" 
     ,camera.get(CV_CAP_PROP_FRAME_WIDTH) 
     ,camera.get(CV_CAP_PROP_FRAME_HEIGHT) 
     ,fps 
     ); 

    int fd; 
    int status; 

    char const * myFIFO = "/tmp/myfifo"; 

    if ((status = mkfifo(myFIFO, 0666)) < 0) { 
     // printf("Fifo mkfifo error: %s\n", strerror(errno)); 
     // exit(EXIT_FAILURE); 
    } else { 
     cout << "Made a named pipe at: " << myFIFO << endl; 
    } 

    cout << "\n\nHit any key to continue after running one of the previously listed commands..." << endl; 
    cin.get(); 

    if ((fd = open(myFIFO,O_WRONLY|O_NONBLOCK)) < 0) { 
     printf("Fifo open error: %s\n", strerror(errno)); 
     exit(EXIT_FAILURE); 
    } 

    while (true) 
    { 
     if (waitKey(1) > 0) 
     { 
      break;  
     } 

     Mat colorImage; 
     camera >> colorImage; 

     // method: named pipe as matrix writes data to the named pipe, but image has glitch 
     size_t bytes = colorImage.total() * colorImage.elemSize(); 

     if (write(fd, colorImage.data, bytes) < 0) { 
      printf("Error in write: %s \n", strerror(errno)); 
     }    
    } 

    close(fd); 

    exit(EXIT_SUCCESS); 
} 
+0

ли мой ответ разберется ваша проблема? Если да, пожалуйста, подумайте о том, чтобы принять его как ваш ответ - нажав полый зеленый галочку/галочку рядом с подсчетом голосов. Если нет, скажите, пожалуйста, что не сработало, чтобы я или кто-то еще помог вам дальше. Благодарю. http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235 –

+0

При переходе к другому проекту нужно было перейти. Будет проверять, что этот ответ будет работать сегодня вечером. –

+0

Это сработало очень хорошо. Благодаря! –

ответ

2

Он отлично работает на шахте ... если убрать O_NONBLOCK из open() вызова.

Кроме того, вместо использования:

cat /tmp/myfifo | ffplay .... -i pipe: 

вы можете просто использовать:

ffplay ... -i /tmp/myfifo 
0
#include <io.h> 
#include <fcntl.h> 
..... 
_setmode(_fileno(stdout), _O_BINARY); 

..... 
cv::cvtColor(frame, frame, CV_BGR2RGBA); 
      for (int i = 0; i < frame.rows; ++i) { 
       uchar* ptr = frame.data + i * 4 * frame.cols; 

       for (int j = 0; j < frame.cols * 4; ++j) { 
        std::cout.write((const char*)(ptr + j), 1); 

       } 
      } 


your.exe | ffplay -an -f rawvideo -vcodec rawvideo -pixel_format bgr32 -video_size 640x480 -i - 
+0

Вы должны указать объяснение своего решения. – eyllanesc

+0

Это решает проблему, и ясно программисту – rtsg

+0

Это может быть ясно для некоторых, но не для всех, хороший ответ должен содержать краткое объяснение, чтобы я помогал всем программистам. – eyllanesc

Смежные вопросы