我的应用大体功能是这样的,使用opencv的接口,从摄像头实时读取color数据显示,并完全保存所有视频到硬盘,已经点击按钮之后将当前的数据帧保存为图片存储到硬盘。

第一个错误:

第二个错误:

void FaceCapture::showColor(cv::Mat colorFrame)

{

//colorframeMutex.lock();

m_colorFrame = colorFrame;

if (g_colorWriter.isOpened())

{

g_colorWriter << colorFrame;

}

//colorframeMutex.unlock();

//cv::resize(colorFrame, frameForShow, dsize );

int img_width = colorFrame.cols; // 在这行发生如上错误,上面两个错误都有可能发生。

int img_height = colorFrame.rows;

int channelnum = colorFrame.channels();

if (NULL == g_prgbdatabuff)

{

g_prgbdatabuff = (uchar *)malloc(img_width * img_height * channelnum);

}

uchar* colorData = colorFrame.data;

bool isColorImgTwoDark = true;

int MaxValueCount = 0;

for (int i = 0; i < img_width * img_height; i++)

{

int rgbaOffset = i * channelnum;

g_prgbdatabuff[rgbaOffset] = colorData[rgbaOffset + 2];

g_prgbdatabuff[rgbaOffset + 1] = colorData[rgbaOffset +1];

g_prgbdatabuff[rgbaOffset + 2] = colorData[rgbaOffset];

if ((255 == colorData[rgbaOffset + 2])

&& (255 == colorData[rgbaOffset + 1])

&& (255 == colorData[rgbaOffset]))

{

MaxValueCount++;

isColorImgTwoDark = false;

}

if ((IMG_DARKNESS_THRESHOLD <= colorData[rgbaOffset + 2])

|| (IMG_DARKNESS_THRESHOLD <= colorData[rgbaOffset + 1])

|| (IMG_DARKNESS_THRESHOLD <= colorData[rgbaOffset]))

{

isColorImgTwoDark = false;

}

}

QImage img(g_prgbdatabuff, img_width, img_height, QImage::Format_RGB888);

QPixmap pixmap = QPixmap::fromImage(img);

QPixmap scaredPixmap = pixmap.scaled(ui.label_color->width(), ui.label_color->height());

ui.label_color->setPixmap(scaredPixmap);

if (IMG_COLOR_OVER_EXPOSURE_PIXEL_COUNT <= MaxValueCount)

{

//ui.label_color_quality->setStyleSheet("color: rgb(255,0,0);");

ui.label_color_quality->setText(QString::fromLocal8Bit("Color图像过度曝光"));

}

else if (true == isColorImgTwoDark)

{

//ui.label_color_quality->setStyleSheet("color: rgb(255,0,0);");

ui.label_color_quality->setText(QString::fromLocal8Bit("Color图像过暗"));

}

else

{

//ui.label_color_quality->setStyleSheet("color: rgb(0,0,0);");

ui.label_color_quality->setText(QString::fromLocal8Bit("Color图像正常"));

}

//free(data);

}

遇到这个问题,非常头大,网上的说法也乱七八糟。基本找不到一个可行的解决方案。而且这个问题也不是每一个数据帧都出现,不断的测试,突然什么时候就崩出来。

针对这个问题,第一反应是colorFrame 的Mat结构被破坏了。然后开始找各种关于Mat的信息。首先寻找判断判断Mat是否有效的两个函数:empty(如果Mat的data区域没有数据,或者尚未开辟空间,则返回false。),另一个是continuous(用来判断Mat中的数据是否是连续内存存的);加入如上两个判断之后发现虽然Mat比较大,1280*800的分辨率存储color数据,但是这两个判断基本上也都能通过,最后了解到像Mat结构确实比较特殊,Mat的赋值运算= 不会开辟新的空间,只会增加引用计数,于是找到可以使用clone或者copyto来进行深copy,多次尝试之后依然无法解决问题。另外了解到Mat 作为参数时,及时是直接传值其实也是传指针。搞过来搞过去,还是无法解决问题。

调用上面showColor函数的调用函数是如下的线程函数:

void ColorThread(VideoCapture cap)

{

cv::Mat input_image;

Rect faceRect;

clock_t currentTime;

bool isReadOk;

while (g_running)

{

isReadOk = cap.read(input_image);

if (false == isReadOk)

{

continue;

}

if (input_image.empty())

{

continue;

}

//这里拿到彩色图之后对图像进行人脸检测,检测成功后可以根据一定的条件设置ROI曝光

detectFace(input_image, faceRect);

currentTime = clock();

if (currentTime - LastSetRoiTime > (1 * CLOCKS_PER_SEC))

{

if (faceRect.width > 50)

{

if (!CAEParamSetting::setAEROIArea(faceRect))

{

logUtil.error("WRITER BUFFER ERROR");

}

}

LastSetRoiTime = currentTime;

}

g_io_mutex.lock();

g_w->showColor(input_image);

g_io_mutex.unlock();

}

}

根据上面的函数我又猜想是不是g_io_mutex使用lock不合适,showColor发生异常导致锁无法释放,于是改用lock_guard来包装g_io_mutex。这个方法也不凑效。

于是开始使用懒人定位法,一行一行注释掉看到底是哪一行发生问题。结果把g_w->showColor(input_image);注释掉后没发生问题。于是就盯着这个函数。然后进入这个函数,再一行一行的注释看是否能发生问题。最后发现,把如下保持视频的代码注释掉之后:

if (g_colorWriter.isOpened())

{

g_colorWriter << colorFrame;

}

这个问题很难出现。于是想到是不是得给主线程中操作g_colorWriter的地方加锁,g_colorWriter在应用中也会进行多次open及release。保证互斥访问。加锁之后果然问题解决。

应用中还有一个保存m_colorFrame图片到硬盘的imwrite操作,再刚才的调试过程中是注释掉的,现在放开之后,会再imwrite保存图片的地方也出现上述问题。于是在imwrite的地方加了同一把锁g_io_mutex。在这里加锁之后,问题果然解决。

到此,其实问题的原因已经比较清楚了,这是一个多线程访问共享数据,导致访问数据冲突出现的问题。

但是遇到另外一个问题。界面上的操作变得非常卡,于是想到应该是g_io_mutex锁保护的关键区域太多导致。将不必要的操作放到锁的外面,缩小关键区域之后,界面也不卡了。问题顺利解决。

一个 将一个无效参数传递给了将无效参数视为严重错误的函数 及写入位置时发生访问冲突的问题的解决相关推荐

  1. findContours函数报错:“将一个无效参数传递给了将无效参数视为严重错误的函数”解决方案之一

    在使用findContours函数时,release可以通过,debug一直在报错:"将一个无效参数传递给了将无效参数视为严重错误的函数". 这里有个大牛汇集的好多种解决方法: h ...

  2. 【C++】VS中读写操作(fclose.cpp)引发中断——将一个无效参数传递给了将无效参数视为严重错误的函数

    [C++]VS中读写操作(fclose.cpp)引发中断--将一个无效参数传递给了将无效参数视为严重错误的函数 遇到的问题 跑数据测试程序时,突然跳出报错中断信息,显示触发断点,错误如下图所示. 但是 ...

  3. 0x0FF0ED76 (ucrtbased.dll) (Project5.exe 中)处有未经处理的异常: 将一个无效参数传递给了将无效参数视为严重错误的函数。 出现了

    void drop(int a)//一个删除deque容器中元素的函数{deque<int>::iterator it;it = kn.begin();kn.erase(it+a);cou ...

  4. C++ 读取文件时报错“将一个无效参数传递给了将无效参数视为严重错误的函数”解决方法

    ** C++ 读取文件时报错"将一个无效参数传递给了将无效参数视为严重错误的函数"解决方法 最近在运行工程时需要读取stl网格文件,但是在运行时发现报错如下: 但是之前运行过一个测 ...

  5. findContours函数报错:“将一个无效参数传递给了将无效参数视为严重错误的函数”解决方案

    先说一下出错时的环境配置:Win10+VS2015+OpenCV3.2.0 在编写火焰检测程序时候,用到findCoutours函数提取火焰边缘轮廓,以便找寻静态特征.但是在调试运行时,弹出:&quo ...

  6. 0x00007FFE9071C408 (ucrtbase.dll) (xxx.exe 中)处有未经处理的异常: 将一个无效参数传递给了将无效参数视为严重错误的函数。

    1.调试VS程序,弹出异常:0x00007FFE9071C408 (ucrtbase.dll) (xxx.exe 中)处有未经处理的异常: 将一个无效参数传递给了将无效参数视为严重错误的函数. 2.在 ...

  7. 用于调用的参数太少/写入位置时发生冲突/检测到无效的异常处理程序例程

    用于调用的参数太少/写入位置时发生冲突/检测到无效的异常处理程序例程 针对新人学C过程中可能遇到的一类问题 我们在学习中经常遇到这种情况: #include<stdio.h> void m ...

  8. VS中fseek.cpp引发断点——将一个无效参数传递给了将无效参数视为严重错误的函数

    错误界面: 原因: stream无效,文件打开失败. 可能路径没写?可能没有该文件?再或者文件被占用? 可能其它因素导致文件没有被打开,stream文件流是无效的. 当你传了个无效参数去访问文件或者内 ...

  9. C++将一个无效参数传递给了将无效参数视为严重错误的函数

    编译项目出错如下 打开调用堆栈,查看调用列表 最终定位到下面代码,文件没有写入的权限,导致无法读取文件而出错  由于没有成功写入ini文件,所以下面就无法读取ini文件

最新文章

  1. Android App自适应draw9patch不失真背景
  2. COM+在win2003+IIS+MSSQL环境下的部署步骤
  3. python3开发工具推荐_python开发工具有哪些?我推荐这5款python开发工具!
  4. 条款9:避免隐藏标准形式的new
  5. bootscripttable前端排序无效_前端你应该知道的八条bug分享给你们
  6. 如何设置工作流到了某一节点自动执行java方法_2019年JAVA最常见面试题汇总(收藏)...
  7. 防范网络*** 应用层防护是重点
  8. velodyne显示点云中grid的单位_孝感好的舞台背景显示屏施工创新服务_胜辉屏安...
  9. 简明 Vim 练级攻(转自coolshell)
  10. stringbuilder寻找字符串位置可能存在多个 java_java面试题整理(一)
  11. VC运行库修复安装一键安装
  12. Java jdk的下载与安装
  13. ILSVRC2012下载+训练
  14. Excel科学计数法转换成文本完整显示
  15. GC bias GC偏好
  16. 文字转化为二维码(数据加密)
  17. 焦虑症是精神病吗?缓解焦虑症的方法有哪些
  18. 北工大2014c语言真题及答案新课标,北京工业大学2006--2007学年《面向对象程序设计》期末考试题及答案...
  19. 双11_淘宝双11_天猫双11_双11是什…
  20. Mapbox离线字体 glyphs

热门文章

  1. 渗透神器burpsuite的汉化
  2. 算法很美第一章 位运算的奇巧淫技
  3. win10修改服务器时间,win10设置时间服务器地址
  4. openGL绘制带纹理地球,并实现鼠标键盘控制
  5. 数字人民币专利数激增, “区块链”领域大有可为
  6. 人工智能在物流领域中的应用
  7. 计算机的6种典型应用领域,人工智能已经广泛应用到许多领域,其典型的应用包括这些...
  8. html页面数据的维护
  9. 林亦杉厦门大学计算机学院,挥别厦大,点燃未来-厦门大学计算机科学系
  10. 自动适配跳转电脑PC端和手机WAP端