我试图获取光标下的颜色(rgb值)。当我编译代码并运行它时我的程序有一个框,在thing_1.exe中有一个" 0x00007FFBF64B3C58处的未处理异常:Microsoft C ++异常:cv ::内存位置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;
}
答案 0 :(得分:1)
您确定GetActiveWindow返回有效的HWND吗?您的控制台应用程序没有窗口消息队列。
NULL hwnd将使您对ScreenToClient的调用失败,并且cursorPosition仍然在屏幕坐标中。为了使您的计划有效,您可以从:
开始答案 1 :(得分:0)
我不太了解opencv,但看来你的矩阵需要初始化...对不起,我想
如何将帧的声明移出循环,并指定其大小和深度?您也可以将调用移到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...
...
答案 2 :(得分:0)
找到错误的关键是获取完整的错误消息:
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 projects\3rdparty\opencv-3.2\opencv\build\include\opencv2\core\mat.inl.hpp, line 957
最重要的部分,即文件名和行号。在第957行,文件mat.inl.hpp我们找到了这个有趣的代码:
CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
这是错误的来源。我会让你调查一下,但这实际上意味着Mat期望模板参数调用frame.at&lt;&gt;()为BYTE,这可以通过stdout std::cout >> frame.elemsize1().
这是我的程序版本,安装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;
}
希望这会帮助你前进。