OpenCV Error: Assertion failed (((((sizeof(size_t)<<28)|0x8442211).... line 957

OpenCV Error: Assertion failed (((((sizeof(size_t)<<28)|0x8442211).... line 957

我正在尝试获取光标下的颜色(rgb 值)。当我的代码被编译并且我 运行 它是我的程序时,有一个框显示 "Unhandled exception at 0x00007FFBF64B3C58 in thing_1.exe: Microsoft C++ exception: cv::Exception at memory location 0x0000001DA30FEFB0."。当我按继续时,框就会回来。我是编码新手,所以这可能是一个新手错误,对于我凌乱的代码感到抱歉...

#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <Windows.h>

using namespace cv;
using namespace std;

boolean k = true;

POINT cursorPosition;

HWND hWnd;

int main(int argc, char* argv[]){
 VideoCapture cap(0);

 while (1){
    Mat frame;

    bool bSuccess = cap.read(frame);

    imshow("Video", frame);

    if (waitKey(10) == 27){
        break;
    }

    if (k == true){
        hWnd = GetActiveWindow();
        k = false;
    }

     GetCursorPos(&cursorPosition);
     ScreenToClient(hWnd, &cursorPosition);

     if (cursorPosition.x < 0) {cursorPosition.x = 0;}
     if (cursorPosition.x > 640) {cursorPosition.x = 640;}
     if (cursorPosition.y < 0) {cursorPosition.y = 0;}
     if (cursorPosition.y > 479) {cursorPosition.y = 479;}

        Vec4b intensity = frame.at<Vec4b>(cursorPosition.x, cursorPosition.y);

        uchar blue = intensity.val[0];
        uchar green = intensity.val[1];
        uchar red = intensity.val[2];

        std::cout << "red = " << int(red) << " | green = " << int(green) << " | blue = " << int(blue) << " | X: " << cursorPosition.x << " |Y: " << cursorPosition.y << std::endl;
  }
 return 0;
 }

您确定 GetActiveWindow returns 是有效的 HWND 吗?您的控制台应用程序没有 window 消息队列。

NULL hwnd 将使您对 ScreenToClient 的调用失败,并且 cursorPosition 仍在屏幕坐标中。要使您的程序正常运行,您可以从以下方面着手:

  • 调用 GetConsoleWindow() 获取 HWND,返回值将在您的应用程序持续时间内有效,因此只调用一次。检查你得到的HWND不为NULL!!
  • 获取框架的 x、y 大小,这样您就可以检查您的客户端坐标 cursorPosition 是否在范围内。 - 这很可能是导致崩溃的原因。
  • 在访问之前始终检查 cursorPosition 是否在 Mat 框架的范围内。在访问具有来自第三方的坐标的 table 时,您应该始终 执行边界检查。

我不太了解 opencv,但您的矩阵似乎需要初始化...抱歉,我认为

如何将 frame 的声明移出循环,并指定其大小和深度?您也可以将对 GetConsoleWindow() 的调用也从那里移开...您的 main() 的顶部应该如下所示:

void main()
{
   VideoCapture cap(0);
   HWND hwnd = GetActiveWindow();
   if (!hwnd)
   {
       std::cout << "Error!!  hwnd is NULL\n";
       return 3;
   }
   Mat frame(640, 480, CV_U8C3);  

   while (1)
   {
      cap.grab();
      cap >> frame;

      // grab cursor pos
 etc...

...

找到错误的关键是获取完整的错误消息:

OpenCV Error: Assertion failed (((((sizeof(size_t)<<28)|0x8442211)>>((DataType<_Tp>::depth) & ((1 << 3) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file c:\users\tika\documents\visual studio projectsrdparty\opencv-3.2\opencv\build\include\opencv2\core\mat.inl.hpp, line 957

最重要的部分是文件名和行号。在文件 mat.inl.hpp 的第 957 行,我们发现这段有趣的代码:

CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());

这就是错误的来源。我会让你调查一下,但这实际上意味着 Mat 期望调用 frame.at<>() 的模板参数是一个 BYTE,正如标准输出 std::cout >> frame.elemsize1().[= 上的快速打印输出所证实的那样14=]

这是你的程序我的版本,安装好opencv后写起来很顺利。它在 C++14 中。

// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

//#include "stdafx.h"
#include <Windows.h>
#include <opencv2/opencv.hpp>


#include <conio.h>
#include <iostream>

int main()
{
    HWND hwnd = ::GetConsoleWindow();
    if (hwnd == NULL)
    {
        std::cout << "Error ! hwnd is NULL\n";
        return 3;
    }

    auto cam = cv::VideoCapture::VideoCapture(0);
    auto frame = cv::Mat();
    POINT pnt = {};

    for (;;)
    {
        cam.grab();
        cam >> frame;

        ::GetCursorPos(&pnt);
        ::ScreenToClient(hwnd, &pnt);

        std::cout << frame.elemSize1() << "cx: " << frame.cols << " cy: " << frame.rows << " x: " << pnt.x << " y: " << pnt.y;

        if (0 < pnt.x && pnt.x < frame.cols
            && 0 < pnt.y && pnt.y < frame.rows)
        {
            const RGBTRIPLE& rgb = *reinterpret_cast<const RGBTRIPLE*>(&frame.at<BYTE>(pnt.y, pnt.x));

            std::cout << " color:"
                << std::setw(4)
                << (unsigned)rgb.rgbtRed
                << std::setw(4)
                << (unsigned)rgb.rgbtGreen
                << std::setw(4)
                << (unsigned)rgb.rgbtBlue;
        }
        std::cout << "\n";
    }

    return 0;
}

希望这对您的前进有所帮助。