Opencv中回调函数调用与二维坐标点排序问题

文章详细描述了如何使用C++和OpenCV库处理图像,捕获鼠标左键点击事件,获取像素值,并根据Y坐标对点击点进行排序。展示了在图像上标记点击点和排序结果的过程。
摘要由CSDN通过智能技术生成
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

struct MyPoint
{
	float x;
	float y;
	MyPoint(float w, float h) : x(w), y(h) {}
};

struct Mydata
{
	Mat img;
	vector<MyPoint> *out;
	Mydata(Mat image, vector<MyPoint> &out0) : img(image), out(&out0) {}
};

void onMouse(int event, int x, int y, int flags, void* param)
{
	Mydata data = *((Mydata*)(param));
	switch (event)
	{
	case EVENT_LBUTTONDOWN:
		//左键按下显示像素值
		if (static_cast<int>((data.img).channels()) == 1)
		{
			//若为灰度图,显示鼠标点击的坐标以及灰度值
			cout << "at(" << x << "," << y << ")value is:" << static_cast<int>((data.img).at<uchar>(x, y)) << endl;
			data.out->push_back(MyPoint(x, y));
		}
		else if (static_cast<int>((data.img).channels() == 3))
		{
			//若图像为彩色图像,则显示鼠标点击坐标以及对应的B, G, R值
			cout << "at (" << x << ", " << y << ")" << endl;
			data.out->push_back(MyPoint(x, y));
		}
		circle(data.img, Point(x, y), 1, Scalar(255, 0, 0), -1);
		putText(data.img, to_string(data.out->size()-1) + ": " + to_string(x) + "," + to_string(y), Point(x, y), FONT_HERSHEY_PLAIN, 1.0, Scalar(255, 255, 0), 1);
		imshow("image", (data.img));
	}
}

struct compare_xy 
{
	vector<MyPoint> result;
	compare_xy(vector<MyPoint> data): result(data) {};
	bool operator ()(const int& i, const int& j) const 
	{
		return (fabs(result[i].y - result[j].y)<1e-3 ? result[i].x < result[j].x : result[i].y < result[j].y);
	}
};

int main()
{
	Mat img = imread("C:\\Desktop\\2.bmp");
	imshow("image", img);
	Mat img2 = img.clone();
	vector<MyPoint> result;
	Mydata data(img, result);
	setMouseCallback("image", onMouse, &data);//鼠标响应函数
	waitKey(0);
	imshow("image1", data.img);
	vector<int> index(result.size(), 0);
	for (int i = 0; i != index.size(); i++) 
	{
		index[i] = i;
	}
	std::sort(index.begin(), index.end(), compare_xy(result));
	for (int i = 0; i < index.size(); i++)
	{
		circle(img2, Point((int)result[index[i]].x, (int)result[index[i]].y), 1, Scalar(255, 0, 0), -1);
		putText(img2, to_string(i) + ": " + to_string((int)result[index[i]].x) + "," + to_string((int)result[index[i]].y), Point((int)result[index[i]].x, (int)result[index[i]].y), FONT_HERSHEY_PLAIN, 1.0, Scalar(255, 255, 0), 1);
	}
	imshow("image2", img2);
	waitKey(0);
	system("pause");
	return 0;
}

python类似

import cv2
def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):
    img_src = param[0]
    if event == cv2.EVENT_LBUTTONDOWN:
        xy = "%d,%d" % (x, y)
        cv2.circle(img_src, (x, y), 1, (255, 0, 0), thickness = -1)
        cv2.putText(img_src, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,
                    1.0, (0,0,0), thickness = 1)
        cv2.imshow("image", img_src)
img = cv2.imread('./test/num_1.jpeg')
a = [0,0] # 验证多余的参数提供使用
cv2.namedWindow("image")
cv2.setMouseCallback("image", on_EVENT_LBUTTONDOWN, [img,a])

while(1):
    if cv2.waitKey(0)&0xFF==27:
        break
cv2.destroyAllWindows()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

誓天断发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值