- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在我的 QtGui 应用程序中使用自定义 OpenCV VideoProcessor 类。我的 MainWindow 有 2 个 ViewerWidgets,用于显示 VideoProcessor 对象产生的输入和输出帧。 VideoProcessor-Object 在这些 ViewerWidget 上获取指针,以便在这些 Widget 上显示处理过的帧。
当我启动应用程序时,GUI 窗口中的所有内容都会响应用户输入。但是当我开始处理时它停止响应。我什至无法关闭窗口或从应用程序菜单中选择某些内容。处理显示正确的输出并继续运行,但窗口不再响应。
这是启动处理的 MainWindow 的插槽:
void MainWindow::on_actionStart_Capture_triggered()
{
// Create instance
p = new VideoProcessor();
// Open video file
p->setInput(0);
// Declare a window to display the video
p->displayInput("Current Frame");
p->displayOutput("Output Frame");
// Play the video at the original frame rate
p->setDelay(1000./p->getFrameRate());
// Set the frame processor callback function
p->setFrameProcessor(canny);
// Start the process
p->run(cvWidgetIn, cvWidgetOut);
}
这是视频处理器。该文件来自 OpenCV Cookbook,我将其更改为在下面代码末尾的 run() 函数中获取指向我的 ViewerWidgets 的指针。
#if !defined VPROCESSOR
#define VPROCESSOR
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "cvwidget.h"
// The frame processor interface
class FrameProcessor {
public:
// processing method
virtual void process(cv:: Mat &input, cv:: Mat &output)= 0;
};
class VideoProcessor {
private:
// the OpenCV video capture object
cv::VideoCapture capture;
// the callback function to be called
// for the processing of each frame
void (*process)(cv::Mat&, cv::Mat&);
// the pointer to the class implementing
// the FrameProcessor interface
FrameProcessor *frameProcessor;
// a bool to determine if the
// process callback will be called
bool callIt;
// Input display window name
std::string windowNameInput;
// Output display window name
std::string windowNameOutput;
// delay between each frame processing
int delay;
// number of processed frames
long fnumber;
// stop at this frame number
long frameToStop;
// to stop the processing
bool stop;
// vector of image filename to be used as input
std::vector<std::string> images;
// image vector iterator
std::vector<std::string>::const_iterator itImg;
// the OpenCV video writer object
cv::VideoWriter writer;
// output filename
std::string outputFile;
// current index for output images
int currentIndex;
// number of digits in output image filename
int digits;
// extension of output images
std::string extension;
// to get the next frame
// could be: video file; camera; vector of images
bool readNextFrame(cv::Mat& frame) {
if (images.size()==0)
return capture.read(frame);
else {
if (itImg != images.end()) {
frame= cv::imread(*itImg);
itImg++;
return frame.data != 0;
}
}
}
// to write the output frame
// could be: video file or images
void writeNextFrame(cv::Mat& frame) {
if (extension.length()) { // then we write images
std::stringstream ss;
ss << outputFile << std::setfill('0') << std::setw(digits) << currentIndex++ << extension;
cv::imwrite(ss.str(),frame);
} else { // then write video file
writer.write(frame);
}
}
public:
// Constructor setting the default values
VideoProcessor() : callIt(false), delay(-1),
fnumber(0), stop(false), digits(0), frameToStop(-1),
process(0), frameProcessor(0) {}
// set the name of the video file
bool setInput(std::string filename) {
fnumber= 0;
// In case a resource was already
// associated with the VideoCapture instance
capture.release();
images.clear();
// Open the video file
return capture.open(filename);
}
// set the camera ID
bool setInput(int id) {
fnumber= 0;
// In case a resource was already
// associated with the VideoCapture instance
capture.release();
images.clear();
// Open the video file
return capture.open(id);
}
// set the vector of input images
bool setInput(const std::vector<std::string>& imgs) {
fnumber= 0;
// In case a resource was already
// associated with the VideoCapture instance
capture.release();
// the input will be this vector of images
images= imgs;
itImg= images.begin();
return true;
}
// set the output video file
// by default the same parameters than input video will be used
bool setOutput(const std::string &filename, int codec=0, double framerate=0.0, bool isColor=true) {
outputFile= filename;
extension.clear();
if (framerate==0.0)
framerate= getFrameRate(); // same as input
char c[4];
// use same codec as input
if (codec==0) {
codec= getCodec(c);
}
// Open output video
return writer.open(outputFile, // filename
codec, // codec to be used
framerate, // frame rate of the video
getFrameSize(), // frame size
isColor); // color video?
}
// set the output as a series of image files
// extension must be ".jpg", ".bmp" ...
bool setOutput(const std::string &filename, // filename prefix
const std::string &ext, // image file extension
int numberOfDigits=3, // number of digits
int startIndex=0) { // start index
// number of digits must be positive
if (numberOfDigits<0)
return false;
// filenames and their common extension
outputFile= filename;
extension= ext;
// number of digits in the file numbering scheme
digits= numberOfDigits;
// start numbering at this index
currentIndex= startIndex;
return true;
}
// set the callback function that will be called for each frame
void setFrameProcessor(void (*frameProcessingCallback)(cv::Mat&, cv::Mat&)) {
// invalidate frame processor class instance
frameProcessor= 0;
// this is the frame processor function that will be called
process= frameProcessingCallback;
callProcess();
}
// set the instance of the class that implements the FrameProcessor interface
void setFrameProcessor(FrameProcessor* frameProcessorPtr) {
// invalidate callback function
process= 0;
// this is the frame processor instance that will be called
frameProcessor= frameProcessorPtr;
callProcess();
}
// stop streaming at this frame number
void stopAtFrameNo(long frame) {
frameToStop= frame;
}
// process callback to be called
void callProcess() {
callIt= true;
}
// do not call process callback
void dontCallProcess() {
callIt= false;
}
// to display the processed frames
void displayInput(std::string wn) {
windowNameInput= wn;
//cv::namedWindow(windowNameInput);
}
// to display the processed frames
void displayOutput(std::string wn) {
windowNameOutput= wn;
//cv::namedWindow(windowNameOutput);
}
// do not display the processed frames
void dontDisplay() {
cv::destroyWindow(windowNameInput);
cv::destroyWindow(windowNameOutput);
windowNameInput.clear();
windowNameOutput.clear();
}
// set a delay between each frame
// 0 means wait at each frame
// negative means no delay
void setDelay(int d) {
delay= d;
}
// a count is kept of the processed frames
long getNumberOfProcessedFrames() {
return fnumber;
}
// return the size of the video frame
cv::Size getFrameSize() {
if (images.size()==0) {
// get size of from the capture device
int w= static_cast<int>(capture.get(CV_CAP_PROP_FRAME_WIDTH));
int h= static_cast<int>(capture.get(CV_CAP_PROP_FRAME_HEIGHT));
return cv::Size(w,h);
} else { // if input is vector of images
cv::Mat tmp= cv::imread(images[0]);
if (!tmp.data) return cv::Size(0,0);
else return tmp.size();
}
}
// return the frame number of the next frame
long getFrameNumber() {
if (images.size()==0) {
// get info of from the capture device
long f= static_cast<long>(capture.get(CV_CAP_PROP_POS_FRAMES));
return f;
} else { // if input is vector of images
return static_cast<long>(itImg-images.begin());
}
}
// return the position in ms
double getPositionMS() {
// undefined for vector of images
if (images.size()!=0) return 0.0;
double t= capture.get(CV_CAP_PROP_POS_MSEC);
return t;
}
// return the frame rate
double getFrameRate() {
// undefined for vector of images
if (images.size()!=0) return 0;
double r= capture.get(CV_CAP_PROP_FPS);
return r;
}
// return the number of frames in video
long getTotalFrameCount() {
// for vector of images
if (images.size()!=0) return images.size();
long t= capture.get(CV_CAP_PROP_FRAME_COUNT);
return t;
}
// get the codec of input video
int getCodec(char codec[4]) {
// undefined for vector of images
if (images.size()!=0) return -1;
union {
int value;
char code[4]; } returned;
returned.value= static_cast<int>(capture.get(CV_CAP_PROP_FOURCC));
codec[0]= returned.code[0];
codec[1]= returned.code[1];
codec[2]= returned.code[2];
codec[3]= returned.code[3];
return returned.value;
}
// go to this frame number
bool setFrameNumber(long pos) {
// for vector of images
if (images.size()!=0) {
// move to position in vector
itImg= images.begin() + pos;
// is it a valid position?
if (pos < images.size())
return true;
else
return false;
} else { // if input is a capture device
return capture.set(CV_CAP_PROP_POS_FRAMES, pos);
}
}
// go to this position
bool setPositionMS(double pos) {
// not defined in vector of images
if (images.size()!=0)
return false;
else
return capture.set(CV_CAP_PROP_POS_MSEC, pos);
}
// go to this position expressed in fraction of total film length
bool setRelativePosition(double pos) {
// for vector of images
if (images.size()!=0) {
// move to position in vector
long posI= static_cast<long>(pos*images.size()+0.5);
itImg= images.begin() + posI;
// is it a valid position?
if (posI < images.size())
return true;
else
return false;
} else { // if input is a capture device
return capture.set(CV_CAP_PROP_POS_AVI_RATIO, pos);
}
}
// Stop the processing
void stopIt() {
stop= true;
}
// Is the process stopped?
bool isStopped() {
return stop;
}
// Is a capture device opened?
bool isOpened() {
return capture.isOpened() || !images.empty();
}
// to grab (and process) the frames of the sequence
void run(CVWidget *inputWidget, CVWidget *outputWidget) {
// current frame
cv::Mat frame;
// output frame
cv::Mat output;
// if no capture device has been set
if (!isOpened())
return;
stop= false;
while (!isStopped()) {
// read next frame if any
if (!readNextFrame(frame))
break;
// display input frame
if (windowNameInput.length()!=0)
// cv::imshow(windowNameInput,frame);
inputWidget->sendImage(&frame);
// calling the process function or method
if (callIt) {
// process the frame
if (process)
process(frame, output);
else if (frameProcessor)
frameProcessor->process(frame,output);
// increment frame number
fnumber++;
} else {
output= frame;
}
// write output sequence
if (outputFile.length()!=0)
writeNextFrame(output);
// display output frame
if (windowNameOutput.length()!=0)
//cv::imshow(windowNameOutput,output);
outputWidget->sendImage(&output);
// introduce a delay
if (delay>=0 && cv::waitKey(delay)>=0)
stopIt();
// check if we should stop
if (frameToStop>=0 && getFrameNumber()==frameToStop)
stopIt();
}
}
};
#endif
最佳答案
虽然我找不到问题的具体原因,但我终于找到了适合我的解决方案:
正如您所建议的,我去掉了这个 VideoProcessor-Utility 类,并通过使用 QTimer 在每个帧之间进行延迟,在 MainWindow 中实现了用于处理帧序列的 Processing-Loop。
我制作了“ProcessorWidget”,而不是 VideoProcessor-Class。这个 GUI 小部件提供了所有输入控件,用于参数化我目前已实现的每个处理器功能。
所有 OpenCV 代码现在都在 ProcessorWidget 类中,它有一个公共(public)插槽 cv::Mat process(cv::Mat input),它只接受输入帧,然后解析来自GUI 并在内部处理正确处理器和参数的选择。
MainWindow 现在构造 ViewerWidgets 和 ProcessorWidget 并拥有 Control 和 Timing。
处理和显示帧现在只是:
cvWidgetOut->sendImage(&processor->processFrame(input));
如果我想添加更多 OpenCV 功能,我不必更改主窗口或 GUI。这一切都在 ProcessorWidget 类中完成。
关于opencv - OpenCV 进程运行时 QMainWindow 没有响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8828679/
我正在尝试从我的系统中完全删除 opencv。我试图学习 ROS,而在教程中我遇到了一个问题。创建空工作区后,我调用catkin_make 它给出了一个常见错误,我在 answers.ros 中搜索并
我在尝试逐步转移对warpAffine的调用时遇到崩溃(不是异常): void rotateImage( const Mat& source, double degree, Mat& output )
如何处理opencv gpu异常?是否有用于opencvgpu异常处理的特定错误代码集api? 我尝试了很多搜索,但只有1个错误代码,即CV_GpuNotSupported。 请帮帮我。 最佳答案 虽
笔记 我是 OpenCV(或计算机视觉)的新手,所以告诉我搜索查询会很有帮助! 我想问什么 我想编写一个从图片中提取名片的程序。 我能够提取粗略的轮廓,但反射光会变成噪点,我无法提取准确的轮廓。请告诉
我想根据像素的某个阈值将Mono16类型的Mat转换为二进制图像。我尝试使用以下内容: 阈值(img,ret,0.1,1,CV_THRESH_BINARY); 尝试编译时,出现make错误,提示: 错
我对使用GPU加速的OpenCV中的卷积函数有疑问。 使用GPU的卷积速度大约快3.5 运行时: convolve(src_32F, kernel, cresult, false, cbuffer);
我正在尝试使用非对称圆圈网格执行相机校准。 我通常找不到适合CirclesGridFinder的文档,尤其是findHoles()函数的文档。 如果您有关于此功能如何工作以及其参数含义的信息,将不胜感
在计算机上绘图和在 OpenCV 的投影仪上投影之间有什么区别吗? 一种选择是投影显示所有内容的计算机屏幕。但也许也有这样的选择,即在投影仪上精确地绘制和投影图像,仅使用计算机作为计算机器。如果我能做
我将Processing(processing.org)用于需要人脸跟踪的项目。现在的问题是由于for循环,程序将耗尽内存。我想停止循环或至少解决内存不足的问题。这是代码。 import hyperm
我有下面的代码: // Image Processing.cpp : Defines the entry point for the console application. // //Save
我正在为某些项目使用opencv。并有应解决的任务。 任务很简单。我有一张主图片,并且有一个模板,而不是将主图片与模板进行比较。我使用matchTemplate()函数。我只是好奇一下。 在文档中,我
我正在尝试使用以下命令创建级联分类器: haartraining -data haarcascade -vec samples.vec -bg negatives.dat -nstages 20 -n
我试图使用OpenCV检测黑色图像中一组形状的颜色,为此我使用了Canny检测。但是,颜色输出总是返回为黑色。 std::vector > Asteroids::DetectPoints(const
我正在尝试使用OpenCv 2.4.5从边缘查找渐变方向,但是我在使用cvSobel()时遇到问题,以下是错误消息和我的代码。我在某处读到它可能是由于浮点(??)之间的转换,但我不知道如何解决它。有帮
我正在尝试构建循环关闭算法,但是在开始开发之前,我想测试哪种功能描述符在真实数据集上效果更好。 我有两个在两个方向拍摄的走廊图像,一个进入房间,另一个离开同一个房间。因此它们代表相同的场景,但具有2个
有没有一种方法可以比较直方图,但例如要排除白色,因此白色不会影响比较。 最佳答案 白色像素有 饱和度 , S = 0 .因此,在创建直方图时很容易从计数中删除白色像素。请执行下列操作: 从 BGR 转
就像本主题的标题一样,如何在OpenCV中确定图像的特定像素(灰度或彩色)是否饱和(例如,亮度过高)? 先感谢您。 最佳答案 根据定义,饱和像素是指与强度(即灰度值或颜色分量之一)等于255相关联的像
我是OpenCV的新用户,正在从事大学项目。程序会获取输入图像,对其进行综合模糊处理,然后对其进行模糊处理。当对合成模糊图像进行反卷积时,会生成边界伪像,因为...好吧,到目前为止,我还没有实现边界条
我想知道OpenCV是haar特征还是lbp是在多尺度搜索过程中缩放图像还是像论文中提到的那样缩放特征本身? 编辑:事实证明,检测器可以缩放图像,而不是功能。有人知道为什么吗?通过缩放功能可以更快。
我在openCv中使用SVM.train命令(已定义了适当的参数)。接下来,我要使用我的算法进行分类,而不是使用svm.predict。 可能吗?我可以访问训练时生成的支持 vector 吗?如果是这
我是一名优秀的程序员,十分优秀!