Мне нужно захватить кадр с веб-камеры примерно 30 раз в секунду. По сути, я ищу способ реализовать следующее:
mainloop:
while( // scan is in process )
{
// process current image
// discard current image and dequeue next image (pop it off the front of the queue)
}
interrupt routine: // execute 30 times per second
{
// capture newImage with webcam
// enqueue newImage (push it onto the back of the queue)
// reset timer and return from interrupt
}
Боюсь, у меня недостаточно опыта, чтобы точно знать, что я ищу. Если кто-нибудь получит лучший совет о том, как делать снимки в фоновом режиме каждые 30 секунд, я был бы рад услышать это. Я новичок в OpenCV, хотя у меня достаточно опыта в C ++ в контексте классной комнаты. Конечная цель моего проекта — использовать обнаружение и сопоставление объектов для извлечения матрицы преобразования кадра в кадр между каждыми двумя кадрами (другими словами, для отслеживания движения камеры по поверхности).
Целевая ОС: OSX Yosemite 10.10.4, работает под управлением XCode 6.3.1
* в конечном итоге это решение будет перенесено на платформу Windows, поэтому я бы хотел найти решение, не зависящее от платформы (или компьютера).
Большинство камер захватывают изображения на свои собственные часы. Тогда вы раб, а не хозяин: вы не запускаете захват изображения. Вместо этого вы будете получать уведомления о появлении нового изображения. Любой API-интерфейс камеры (OpenCV, Qt Multimedia и т. Д.) Позволит вам получать уведомления о появлении новых данных с камеры. Если API не имеет асинхронного уведомления, вы можете вращать поток и выполнять захват синхронно. Скажем, с OpenCV:
void process(const cv::Mat & frame) { ... }
int main() {
bool quit = false;
std::condition_variable queue_cv;
std::mutex queue_mutex;
std::deque<cv::Mat> queue;
auto capture = cv::VideoCapture(0);
// Worker thread - source of frames
auto thread = std::thread([&]{
int frame_count = 0;
while (! quit) {
cv::Mat frame;
if (! capture.read(frame)) break;
frame_count ++;
if (frame_count >= 30) {
std::unique_lock<std::mutex> lock(queue_mutex);
queue.push_back(frame);
lock.unlock();
queue_cv.notify_one();
frame_count = 0;
}
}
quit = true;
});
// Main thread - consumer of frames
while (!quit) {
std::unique_lock<std::mutex> lock(queue_mutex);
queue_cv.wait(queue_lock, []{ return queue.size() > 0; });
// we own the lock here
auto frame = queue.pop_front();
lock.unlock();
// lock is released, process the frame
process(frame);
}
thread.join();
}