OpenCV 3.0 で cvSegmentFGMask
OpenCV 3.0.0 では,IplImage,legacy関数などの1.x系のサポートがなくなっています.
つまりcvHogehogeみたいな関数は使えません.
たいていの機能はcv::Hogehogeみたいな関数が実装されているのですが,一部の関数は代替関数がなくて残念なことになる場合があります.
私の環境でも,一部のプログラムで使っていたcvSegmentFGMaskが使えなくなり,困っていました.
cvSegmentFGMaskは,ノイズっぽいmask画像をいい感じにまとめてくれる関数です.
この度cvSegmentFGMaskをOpenCV 3.0で使えるように1.x系のソースを参考にして2.x系で実装しました.
cvSegmentFGMaskの2.0系実装
cvSegmentFGMask.cpp
#include <opencv2/opencv.hpp> namespace cv { void SegmentFGMask(InputArray src, OutputArray dst, bool poly1Hull0, float perimScale, Point offset=Point(0,0)) { Mat mask = src.getMat().clone(); if(mask.type() != CV_8UC1) throw std::runtime_error("src.type() != CV_8UC1"); Mat new_mask = Mat::zeros(mask.size(), mask.type()); std::vector<std::vector<Point>> contours; findContours(mask, contours,RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, offset); const Scalar white(255); for (int i = 0; i < contours.size(); i++){ double len = cv::arcLength(contours[i], true); double q = (mask.rows + mask.cols) / perimScale; if (len >= q){ std::vector<std::vector<Point>> tmp_contours(1); if (poly1Hull0){ cv::approxPolyDP(contours[i], tmp_contours[0], 2.0, true); } else{ tmp_contours[0] = contours[i]; } drawContours(new_mask, tmp_contours, 0, white, -1, 8,cv::noArray(),-1,Point(-offset.x,-offset.y)); } } new_mask.copyTo(dst); } } int main(){ cv::VideoCapture video("./WalkByShop1cor.mpg"); cv::BackgroundSubtractorMOG bgs; while(1){ cv::Mat image; video >> image; if(image.empty()) break; cv::Mat mask; bgs(image,mask); cv::Mat segmented_mask; cv::SegmentFGMask(mask,segmented_mask,true,16.0f); { cv::Mat tmp; cv::hconcat(mask,segmented_mask,tmp); cv::imshow("mask",tmp); char k = cv::waitKey(1); if(k == 'q') break; } } return 0; }
結果
左が普通の背景差分.右がcv::SegmentFGMaskをかけたものです.
今回のまとめ
必要がなければOpenCV 2.x 系に戻しましょう.