OpenCV:存储鼠标左键点击点的坐标
OpenCV: Storing the coordinates of the points clicked by mouse left button
下面的程序将给出鼠标左键点击的位置。
void onMouse(int evt, int x, int y, int flags, void* param) {
if(evt == CV_EVENT_LBUTTONDOWN) {
cv::Point* ptPtr = (cv::Point*)param;
ptPtr->x = x;
ptPtr->y = y;
}
}
int main() {
cv::Point2i pt(-1,-1);//assume initial point
cv::namedWindow("Output Window");
Mat frame = cv::imread("chhhha.png");
cv::setMouseCallback("Output Window", onMouse, (void*)&pt);
int X, Y;
while(1)
{
cv::imshow("Output Window", frame);
X=pt.x;
Y=pt.y;
cout<<"X and Y coordinates are given below"<<endl;
cout<<X<<'t'<<Y<<endl;
waitKey(10);
}
getch();
}
我想画一条线连接用户点击的两个点。我知道这条线可以通过函数来绘制:
C++: void line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
但是问题是我必须为这个函数提供两点,但是我前面的点丢失了,如下面的代码所示:
void onMouse(int evt, int x, int y, int flags, void* param) {
if(evt == CV_EVENT_LBUTTONDOWN) {
cv::Point* ptPtr = (cv::Point*)param;
ptPtr->x = x;
ptPtr->y = y;
}
}
int main() {
cv::Point2i pt(-1,-1);
cv::namedWindow("Output Window");
Mat frame = cv::imread("chhhha.png");
cv::setMouseCallback("Output Window", onMouse, (void*)&pt);
int X, Y;
while(1)
{
cv::imshow("Output Window", frame);
X=pt.x;
Y=pt.y;
cout<<"X and Y coordinates are given below"<<endl;
cout<<X<<'t'<<Y<<endl;
line(frame, pt1, pt2, 'r', 1, 8, 0); //here I am having only one point. This is the issue
waitKey(10);
}
getch();
}
编辑
那么是否有存储用户点击点坐标的方法。假设用户点击图像上的两个点,我们将两次点击的x坐标存储在x[0]和x[1]中,Y坐标存储在Y[0]和Y[1]中。
然后我可以很容易地使用函数来绘制一条线。请帮助我朝这个方向前进。
提前感谢您的建议。
我的最新代码
using namespace cv;
using namespace std;
void onMouse(int evt, int x, int y, int flags, void* param) {
if(evt == CV_EVENT_LBUTTONDOWN) {
std::vector<cv::Point>* ptPtr = (std::vector<cv::Point>*)param;
ptPtr->push_back(cv::Point(x,y));
}
}
int main()
{
std::vector<Point> points;
cv::namedWindow("Output Window");
Mat frame = cv::imread("chhha.png");
cv::setMouseCallback("Output Window", onMouse, (void*)&points);
int X=0, Y=0;
while(1)
{
cv::imshow("Output Window", frame);
X=points[0].x;
Y=points[0].y;
cout<<"First X and Y coordinates are given below"<<endl;
cout<<X<<'t'<<Y<<endl;
waitKey(10);
}
getch();
}
这有两个主要问题:
1-这将编译得很好,但在运行时它给出Debug Assertion Failed!
错误,
,当我通过放置断点进行调试时:
X=points[0].x;
Y=points[0].y;
它进一步说:
表达式:Vector下标out of range
2-如何跳出while循环?在其他类似的程序中,我注意到它永远留在while循环中。
我建议传递给std::vector<cv::Point>*
而不是传递给cv::Point*
。由于cv::Point
有一个复制构造函数,您可以通过push_back
在那里存储点。
我的意思是:
std::vector<cv:Point> points;
cv::namedWindow("Output Window");
Mat frame = cv::imread("chhhha.png");
cv::setMouseCallback("Output Window", onMouse, (void*)&points);
int X, Y;
while(1)
{
cv::imshow("Output Window", frame);
if (points.size() > 2) //we have 2 points
{
for (auto it = points.begin(); it != points.end(); ++it)
{
cout<<"X and Y coordinates are given below"<<endl;
cout<<(*it).x<<'t'<<(*it).y<<endl;
}
//draw points
}
...
和在回调中:
void onMouse(int evt, int x, int y, int flags, void* param) {
if(evt == CV_EVENT_LBUTTONDOWN) {
std::vector<cv::Point>* ptPtr = (std::vector<cv::Point>*)param;
ptPtr->push_back(cv::Point(x,y));
}
}
之后,您可以使用points[0]
和points[1]
访问前两个点。
编辑:更新了检查向量大小的代码。您应该注意,如果鼠标回调在另一个线程中执行,则该方法可能需要锁定。
相关文章:
- 将字符串存储在c++中的稳定内存中
- QGraphicsPolygonItem在拖动时未更新QPolygonF坐标
- std::原子加载和存储都需要吗
- C++:将控制台输出存储在宏中更好吗
- 使用QProcess执行命令,并将结果存储在QStringList中
- 访问存储在向量C++中的结构的多态成员
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何将 x.y 坐标的值存储在不同的数组中
- 将浮点数组存储在纹理中,并使用纹理坐标从着色器访问浮点
- 存储 (x, y) 与设置的坐标
- QGraphicsScene 或 QGraphicsItem 是否存储场景坐标
- 如何存储坐标以便与以后的坐标进行比较
- 我想使用C++映射,以存储一个矩形id的4个坐标,任何人都可以举一个例子吗
- 创建用于将结构坐标存储为键和线号作为值的映射
- 稀疏矩阵 坐标存储格式:从行主转换为列主
- 如何在 MFC 单文档中存储坐标
- 用于存储坐标的浮点或整数
- C++最好的文件格式存储大量地图坐标
- findnonzero() 中存储向量<Point>中非零元素的坐标时出错
- OpenCV:存储鼠标左键点击点的坐标