<pre name="code" class="cpp">目的:实时监测视频的边缘轮廓。
//边缘检测
void canny(Mat &input, Mat &output)
{
if (input.channels() == 3)//将彩色图像转为灰度图像
{
cvtColor(input, output, CV_BGR2GRAY);
}
Canny(output, output, 100, 200);//计算Canny边缘
threshold(output, output, 128, 255, THRESH_BINARY_INV);//反转图像
}
class VideoProcessor
{
public:
VideoProcessor() : callIt(true), delay(0),
fnumber(0), stop(false), frameToStop(-1){}
//设置回调函数
void setFrameProcessor(void(*frameProcessingCallback)(Mat &, Mat &))
{
process = frameProcessingCallback;
}
//设置视频文件的名称
bool setInput(string filename)
{
fnumber = 0;
//释放之前打开过的资源
capture.release();
//打开视频文件
return capture.open(filename);
}
//创建输入窗口
void displayInput(string wn)
{
windowsNameInput = wn;
namedWindow(windowsNameInput);
}
//创建输出窗口
void displayOutput(string wn)
{
windowsNameOutput = wn;
namedWindow(windowsNameOutput);
}
void dontDisplay()
{
destroyAllWindows();
windowsNameInput.clear();
windowsNameOutput.clear();
}
void stopIt()
{
stop = true;
}
bool isStopped()
{
return stop;
}
bool isOpened()
{
return capture.isOpened();
}
void setDelay(int d)
{
delay = d;
}
bool readNextFrame(Mat&frame)
{
return capture.read(frame);
}
long getFrameNumber()
{
long fnumber = static_cast<long>(capture.get(CV_CAP_PROP_POS_FRAMES));
return fnumber;
}
void callProcess()
{
callIt = true;
}
void dontCallProcess()
{
callIt = false;
}
void stopAtFrameNo(long frame)
{
frameToStop = false;
}
void run()
{
Mat frame;//当前帧
Mat output;//输出帧
if (!isOpened())
{
return;
}
stop = false;
while (!isStopped())
{
//读取下一帧
if (!readNextFrame(frame))
{
break;
}
//显示输出帧
if (windowsNameInput.length()!=0)
{
imshow(windowsNameInput,frame);
}
//调用处理函数
if (callIt)
{
//处理当前帧
process(frame, output);
//增加帧数
fnumber++;
}
else
{
output = frame;
}
//显示输出帧
if (windowsNameOutput.length()!=0)
{
imshow(windowsNameOutput,output);
}
//引入延迟
if (delay>=0&&waitKey(delay)>=0)
{
stopIt();
}
//检测是否需要停止运行
if (frameToStop>=0&&getFrameNumber()==frameToStop)
{
stopIt();
}
}
}
private:
VideoCapture capture;//捕捉视频图像
void(*process)(Mat&, Mat&);//每帧调用回调函数
bool callIt;//确定是否调用回调函数
string windowsNameOutput;//输出窗口名
string windowsNameInput;//输入窗口名
int delay;//延迟
long fnumber;//已处理的帧数
long frameToStop;//在该帧数停止
bool stop;//是否停止
};
void test_VideoProcessor()
{
VideoProcessor processor;
processor.setInput("一剪梅.avi");
processor.displayInput("当前帧");
processor.displayOutput("输出帧");
processor.setDelay(25);//设置延迟
processor.setFrameProcessor(canny);//设置处理回调函数
processor.run();//开始处理
}
<img src="https://img-blog.csdn.net/20151020102503588?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />