2010-06-04 37 views
18

Tôi đã cố gắng tìm/thực hiện chức năng tìm kiếm và tua lại (đối với video (.avi)) bằng cách sử dụng OpenCV trong C++, nhưng tôi không thể tìm ra cách làm, ngoài việc thực hiện toàn bộ tệp một lần và lưu từng hình ảnh. Còn cách nào khác không?OpenCV Seek Function/Rewind

Mọi trợ giúp sẽ được đánh giá cao; Cảm ơn trước!

+1

Bằng cách này cũng giống như mẹo, OpenCV tìm kiếm không hoạt động đúng trên flv nếu bạn gặp khó khăn bất cứ lúc nào để tìm kiếm không hoạt động. Đã cho tôi một ngày để tìm ra nó !!! –

Trả lời

37

Sử dụng cvSetCaptureProperty(), bạn có thể chuyển qua khung, theo mili giây hoặc theo số khung thứ tự.

int cvSetCaptureProperty(CvCapture* capture, int property_id, double value); 

property_id là một tài sản mà bạn sẽ cần phải sử dụng. Nó có thể là một trong những cách sau:

  1. CV_CAP_PROP_POS_MSEC - vị trí trong mili giây từ tập tin bắt đầu
  2. CV_CAP_PROP_POS_FRAMES - vị trí trong khung
  3. CV_CAP_PROP_POS_AVI_RATIO - vị trí trong đơn vị tương đối (0 - bắt đầu tệp, 1 - cuối của tệp)
  4. CV_CAP_PROP_FRAME_WIDTH - chiều rộng của khung trong luồng video (chỉ dành cho máy ảnh)
  5. CV_CAP_PROP_FRAME_HEIGHT - hei ght khung trong luồng video (chỉ dành cho máy ảnh)
  6. CV_CAP_PROP_FPS - tốc độ khung hình (chỉ dành cho máy ảnh)
  7. CV_CAP_PROP_FOURCC - Mã mã gồm 4 ký tự (chỉ dành cho máy ảnh).

Hai điều đầu tiên bạn quan tâm.

EDIT: biết thêm :)

Bạn có thể lướt qua khung chỉ bằng cách liên tục gọi hàm đề cập với chỉ số khung khác nhau.

cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frameIndex); 

Ví dụ:

IplImage* frame; 
CvCapture* capture = cvCreateFileCapture("test.avi"); 

/* iterate through first 10 frames */ 
for (int i = 0; i < 10; i++) 
{ 
    /* set pointer to frame index i */ 
    cvSetCaptureProperty(capture, CV_CAP_POS_FRAMES, i); 

    /* capture the frame and do sth with it */ 
    frame = cvQueryFrame(capture); 
} 

Bạn có thể đặt mã tương tự để thực hiện mỗi người dùng thời gian nhấp vào một nút để chuyển tiếp/tua lại video.

Phương pháp C++ (OpenCV 2 trở lên) sẽ sử dụng phương pháp này thay vì cùng một giá trị property_id và giá trị.

bool VideoCapture::set(int property_id, double value) 
+0

Bất kỳ ví dụ nào? Giả sử tôi có tệp .avi, tôi sẽ sử dụng tệp này như thế nào để quay qua các khung? – Cenoc

+0

Cảm ơn con trỏ bằng cách này. – Cenoc

+0

Đã chỉnh sửa câu trả lời của tôi. – Adi

0

Trong thư viện highgui bạn sẽ tìm thấy các chức năng cho thanh tìm kiếm (cvCreateTrackbar và bạn bè).

+0

cách nó được mô tả nó không giống như một thanh tìm kiếm; Nghe có vẻ là một thanh cuộn thường xuyên. Ngoài ra, tất cả các ví dụ tôi tìm thấy cho nó trực tuyến, sử dụng nó cho shiz ngẫu nhiên khác, giống như thay đổi màu sắc hình ảnh. – Cenoc

+0

Bạn có thể móc thanh trượt vào bất kỳ biến/sự kiện nào bạn muốn - bao gồm vị trí tệp. Bạn cần phải làm một công việc littl emore hơn một thanh tìm kiếm xây dựng nhưng nó có –

1

Tôi nghĩ bạn phải đọc toàn bộ tệp vào một loạt các IplImages, sau đó làm việc thông qua đó. Lý do là, cvQueryFrame là một quá trình một chiều, nó đọc một khung tại một thời điểm theo thứ tự. Tôi không thể nghĩ ra cách nào khác. Tùy thuộc vào độ dài của video thời gian khởi tạo có thể không quá tệ.

Các cvTrackbars giống như bạn nói, chủ yếu được sử dụng để thay đổi thông số. Chúng thay đổi giá trị của một biến (được đưa ra như một tham số ở dạng con trỏ) và ném một hàm gọi lại. Rất tiếc, chúng là các phần tử kiểu nút duy nhất trong HighGUI theo như tôi biết

+0

Wow, cảm ơn rất nhiều. Đoán rằng thu hẹp nó cho tôi; Tôi nghĩ rằng đó có thể là trường hợp. Tôi đoán tôi phải ngừng lười biếng và làm điều đó. – Cenoc