欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Opencv實(shí)現(xiàn)鼠標(biāo)事件與窗口互動(dòng)功能過(guò)程

 更新時(shí)間:2022年12月07日 11:52:37   作者:明月醉窗臺(tái)  
平時(shí)在做圖像處理demo或者研究測(cè)試算法時(shí),經(jīng)常會(huì)用到imshow和鼠標(biāo)的交互,比如在顯示圖像的窗口上畫(huà)點(diǎn)、線、圓、矩形、多邊形等操作,故在此做出用法總結(jié)

1.opencv API及參數(shù)介紹

cv::setMouseCallback(const string& windowname, MouseCallback onMouse, void* userdata=0)
{
    ....
}
// windowname: 要操作的窗口名稱
// onMouse: 鼠標(biāo)事件函數(shù),鼠標(biāo)事件發(fā)生以后,要執(zhí)行的回調(diào)函數(shù)。函數(shù)原型是 
// void onMouse(int event, int x, int y, int flags, void * para)
// userdata: 回調(diào)函數(shù)的參數(shù)

鼠標(biāo)回調(diào)函數(shù)介紹:

void onMouse(int event, int x, int y, int flags, void *para)
// int event: 鼠標(biāo)事件,見(jiàn)后續(xù)說(shuō)明
// x, y 是鼠標(biāo)在圖像坐標(biāo)系中的坐標(biāo)
// flags :
// para: 是用戶傳遞到回調(diào)函數(shù)中的參數(shù)

截取感興趣區(qū)域ROI:

cv::selectROIs("MultiTracker", frame, bboxes_, showCrosshair, fromCenter);
// “MultiTracker” : windowsName
// frame: 當(dāng)前畫(huà)面;格式為cv::Mat
// bboxes: 要存儲(chǔ)的框框格式為:std::vector<cv::Rect>
// showCrosshair:默認(rèn)為True
// fromCenter:從中心點(diǎn)還是從對(duì)角點(diǎn),默認(rèn)為false,為true時(shí),選框從中心點(diǎn)開(kāi)始

涉及的相關(guān)參數(shù):

// EVENT的參數(shù)定義
enum
{
	CV_EVENT_MOUSEMOVE =0,//滑動(dòng)
	CV_EVENT_LBUTTONDOWN =1,//左鍵點(diǎn)擊
	CV_EVENT_RBUTTONDOWN =2,//右鍵點(diǎn)擊
	CV_EVENT_MBUTTONDOWN =3,//中鍵點(diǎn)擊
	CV_EVENT_LBUTTONUP =4,//左鍵放開(kāi)
	CV_EVENT_RBUTTONUP =5,//右鍵放開(kāi)
	CV_EVENT_MBUTTONUP =6,//中鍵放開(kāi)
	CV_EVENT_LBUTTONDBLCLK =7,//左鍵雙擊
	CV_EVENT_RBUTTONDBLCLK =8,//右鍵雙擊
	CV_EVENT_MBUTTONDBLCLK =9//中鍵雙擊
};
enum
{
CV_EVENT_FLAG_LBUTTON =1,//左鍵拖拽
CV_EVENT_FLAG_RBUTTON =2,//右鍵拖拽
CV_EVENT_FLAG_MBUTTON =4,//中鍵拖拽
CV_EVENT_FLAG_CTRLKEY =8,//按CTRL不放
CV_EVENT_FLAG_SHIFTKEY =16,//按SHIFT不放
CV_EVENT_FLAG_ALTKEY =32//按ALT不放
};

或者python-opencv中的參數(shù)也相同:

# mouse callback function
def mouse_event(event, x, y, flags, param):
    '''
    :param event: 點(diǎn)擊事件標(biāo)識(shí)
    :param x: 坐標(biāo)x
    :param y: 坐標(biāo)y
    :param flags:按鍵事件標(biāo)識(shí)
    :param param: 攜帶參數(shù)
    :return:
    '''
    if flags == cv2.EVENT_FLAG_ALTKEY:
        print('摁住Alt')
    if flags == cv2.EVENT_FLAG_CTRLKEY:
        print('摁住Ctrl')
    if flags == cv2.EVENT_FLAG_SHIFTKEY:
        print('摁住Shift')
    if flags == cv2.EVENT_FLAG_LBUTTON:
        print('摁住左鍵')
    if flags == cv2.EVENT_FLAG_MBUTTON:
        print('摁住中鍵')
    if flags == cv2.EVENT_FLAG_RBUTTON:
        print('摁住右鍵')
    if event == cv2.EVENT_LBUTTONDBLCLK:
        print('左鍵雙擊')
    if event == cv2.EVENT_MBUTTONDBLCLK:
        print('中鍵雙擊')
    if event == cv2.EVENT_RBUTTONDBLCLK:
        print('右鍵雙擊')
    if event == cv2.EVENT_LBUTTONDOWN:
        print('左鍵擊下')
    if event == cv2.EVENT_LBUTTONUP:
        print('左鍵彈起')
    if event == cv2.EVENT_MBUTTONDOWN:
        print('中鍵擊下')
    if event == cv2.EVENT_MBUTTONUP:
        print('中鍵彈起')
    if event == cv2.EVENT_RBUTTONDOWN:
        print('右鍵擊下')
    if event == cv2.EVENT_RBUTTONUP:
        print('右鍵彈起')
    if event == cv2.EVENT_MOUSEWHEEL:
        if flags > 0:
            print('向前滾動(dòng)')
        else:
            print('向后滾動(dòng)')
    if event == cv2.EVENT_MOUSEHWHEEL:
        if flags > 0:
            print('向左滾動(dòng)')  # 按住Alt
        else:
            print('向右滾動(dòng)')
if __name__ == '__main__':
    img = np.mat(np.zeros((300, 300, 3), np.uint8))  # 構(gòu)造一個(gè)像素值全為1的圖形
    cv2.namedWindow('mouse')    #命名窗口為mouse
    cv2.setMouseCallback('mouse', mouse_event)  # 窗口與回調(diào)函數(shù)綁定
    while True:
        cv2.imshow('mouse', img)
        if cv2.waitKey(1) & 0xFF == ord('q'):  # 摁下q退出
            break
    cv2.destroyAllWindows()            #銷毀所有窗口

2.一個(gè)可以繪制矩形和控制縮放的demo

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define WINNAME "畫(huà)板"
struct MouseParam
{
	Mat img; //用于畫(huà)好一個(gè)后顯示
	Mat imgZoomBackup; //用于zoom的還原備份
	Mat imgTmp; //用于實(shí)時(shí)顯示
	Mat imgBackup; //清空,顯示最初的圖
	Point pt1;
	Point pt2;
	bool mouseLflag;
	float scale;
};
//繪制矩形
void draw_rectangle(Mat& img, const Point& pt1, const Point& pt2)
{
	rectangle(img, pt1, pt2, Scalar(0, 255, 0), 1, 0, 0);
}
//繪制十字線:即過(guò)一點(diǎn)的水平、豎直線
void draw_crossline(Mat& img, const Point& pt)
{
	int width = img.cols;
	int height = img.rows;
	cv::Point ptv1;
	cv::Point ptv2;
	cv::Point pth1;
	cv::Point pth2;
	ptv1 = cv::Point(pt.x, 0);
	ptv2 = cv::Point(pt.x, height);
	pth1 = cv::Point(0, pt.y);
	pth2 = cv::Point(width, pt.y);
	cv::line(img, ptv1, ptv2, Scalar(255, 255, 0), 1);
	cv::line(img, pth1, pth2, Scalar(255, 255, 0), 1);
}
/*
* func:實(shí)現(xiàn)圖像繞某一點(diǎn)進(jìn)行縮放功能
*/
void zoom(Mat& img, const Mat& srcimg, const Point& pt, const float scale)
{
	int x1, y1, x2, y2;
	int width, height;
	width = (int)(srcimg.cols * scale / 2.0);
	height = (int)(srcimg.rows * scale / 2.0);
	x1 = max(pt.x - width, 0);
	y1 = max(pt.y - height, 0);
	x2 = min(pt.x + width, srcimg.cols);
	y2 = min(pt.y + height, srcimg.rows);
	Rect zoomRect(Point(x1, y1), Point(x2, y2));
	img = srcimg(zoomRect).clone();
}
void on_mouse(int event, int x, int y, int flags, void* param)
{
	MouseParam* par = (MouseParam*)param;
	Point pt(x, y);
	double value;
	float step = 0.05;
	if (event == EVENT_RBUTTONDOWN) //按下右鍵,重畫(huà)
	{
		par->img = par->imgBackup.clone();
	}
	else if (event == EVENT_LBUTTONDOWN)  //按下左鍵
	{
		par->pt1 = pt;
		par->pt2 = pt;
		par->mouseLflag = true;
	}
	else if (event == EVENT_MOUSEMOVE && flags == EVENT_FLAG_LBUTTON) //按下左鍵并移動(dòng)
	{
		par->pt2 = pt;
	}
	else if (event == EVENT_LBUTTONUP)//左鍵放開(kāi)進(jìn)行繪制矩形框
	{
		par->pt2 = pt;
		draw_rectangle(par->img, par->pt1, par->pt2);
		//par->imgZoomBackup = par->img.clone();
		par->mouseLflag = false;
	}
	else if (event == EVENT_MOUSEMOVE)  //鼠標(biāo)移動(dòng)將顯示十字線
	{
		par->pt1 = pt;
	}
	else if (event == EVENT_MOUSEWHEEL) //鼠標(biāo)滾動(dòng)
	{
		value = getMouseWheelDelta(flags);
		if (value > 0)             //滾輪向前滾動(dòng),設(shè)為縮小
			par->scale += step;   
		else if (value < 0)        //鼠標(biāo)向后滾動(dòng),設(shè)為放大
			par->scale -= step;
		par->scale = max((float)0.3, par->scale);
		par->scale = min((float)1.0, par->scale);
		zoom(par->img, par->imgZoomBackup, par->pt1, par->scale);
	}
}
int main()
{
	//Mat img(512, 512, CV_8UC3, Scalar::all(255));
	Mat img = imread("./imgs/1/L.png");
	MouseParam mouseParam;
	mouseParam.img = img.clone();
	mouseParam.imgBackup = img.clone();
	mouseParam.imgZoomBackup = img.clone();
	mouseParam.mouseLflag = false;
	float step = 0.05;
	mouseParam.scale = 1.0;
	namedWindow(WINNAME, 0);
	setMouseCallback(WINNAME, on_mouse, &mouseParam);
	int key;
	while (1)
	{
		mouseParam.imgTmp = mouseParam.img.clone();
		draw_crossline(mouseParam.imgTmp, mouseParam.pt1);
		if (mouseParam.mouseLflag == true)
			draw_rectangle(mouseParam.imgTmp, mouseParam.pt1, mouseParam.pt2);
		imshow(WINNAME, mouseParam.imgTmp);
		key = waitKey(40);
		if (key == 27)
		{
			break;
		}
		else if (key == toascii('q'))
		{
			mouseParam.scale -= step;
			zoom(mouseParam.img, mouseParam.imgZoomBackup, mouseParam.pt1, mouseParam.scale);
		}
		else if (key == toascii('e'))
		{
			mouseParam.scale += step;
			zoom(mouseParam.img, mouseParam.imgZoomBackup, mouseParam.pt1, mouseParam.scale);
		}
	}
	return 0;
}

3.圖象中畫(huà)點(diǎn)

  • 對(duì)于拼接后的圖像顯示窗口,依次繪制左右圖中的對(duì)應(yīng)點(diǎn)程序
  • 右鍵刪除尚未調(diào)通
std::vector<cv::Point2f>pointsL; //依次存放左右圖中的對(duì)應(yīng)點(diǎn)
std::vector<cv::Point2f>pointsR;
cv::Mat mask;
cv::Point2f p_;
//鼠標(biāo)回調(diào)函數(shù)
void on_mouse(int event, int x, int y, int flags, void* param)
{
	float cols = mask.cols/2;
	int rad = 6;
	if (event == cv::EVENT_LBUTTONUP || !(flags & cv::EVENT_FLAG_LBUTTON))
		cv::Point2f pt = cv::Point2f(-10, -10);
	else if (event == cv::EVENT_LBUTTONDOWN)
	{
		cv::Point2f pt(x, y);
		if (pt.x>=0&&pt.x <= cols)
		{
			pointsL.push_back(pt);
			cv::circle(mask, pt, rad, cv::Scalar(0, 255, 0), 2);
		}
		else {
			pointsR.push_back(pt);
			cv::circle(mask, pt, rad, cv::Scalar(0, 0, 255), 2);
		}
		//cv::circle(mask, pt, 2, cv::Scalar(0, 255, 0), 2);
		cv::imshow("image", mask);
	}
	else if (event == cv::EVENT_RBUTTONDOWN) //按下右鍵,重畫(huà)
	{
		cv::Point2f pt(x, y);
		if (pointsL.size()>0)
		{
			pointsL.pop_back();
		}
		else if (pointsR.size() > 0)
		{
			pointsR.pop_back();
		}
	}
	std::cout << "pointsL" << std::endl;
	for (int i = 0; i < pointsL.size(); ++i)
	{
		std::cout << pointsL[i] << std::endl;
	}
	std::cout << "pointsR" << std::endl;
	for (int i = 0; i < pointsR.size(); ++i)
	{
		std::cout << pointsR[i] << std::endl;
	}
}

4.opencv例程分水嶺分割中的界面應(yīng)用

鼠標(biāo)時(shí)間包含繪制直線的交互操作

static void help(char** argv)
{
	cout << "\nThis program demonstrates the famous watershed segmentation algorithm in OpenCV: watershed()\n"
		"Usage:\n" << argv[0] << " [image_name -- default is fruits.jpg]\n" << endl;
	cout << "Hot keys: \n"
		"\tESC - quit the program\n"
		"\tr - restore the original image\n"
		"\tw or SPACE - run watershed segmentation algorithm\n"
		"\t\t(before running it, *roughly* mark the areas to segment on the image)\n"
		"\t  (before that, roughly outline several markers on the image)\n";
}
Mat markerMask, img;
Point prevPt(-1, -1);
static void onMouse(int event, int x, int y, int flags, void*)
{
	if (x < 0 || x >= img.cols || y < 0 || y >= img.rows)
		return;
	if (event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON))
		prevPt = Point(-1, -1);
	else if (event == EVENT_LBUTTONDOWN)
		prevPt = Point(x, y);
	else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))
	{
		Point pt(x, y);
		if (prevPt.x < 0)
			prevPt = pt;
		line(markerMask, prevPt, pt, Scalar(12,234,12), 40, 8, 0);
		line(img, prevPt, pt, Scalar(12,234,12), 40, 8, 0);
		prevPt = pt;
		imshow("image", img);
	}
}
int main(int argc, char** argv)
{
	cv::CommandLineParser parser(argc, argv, "{help h | | }{ @input | fruits.jpg | }");
	if (parser.has("help"))
	{
		help(argv);
		return 0;
	}
	//string filename = samples::findFile(parser.get<string>("@input"));
	Mat img0 = imread("..."), imgGray;
	if (img0.empty())
	{
		cout << "Couldn't open image ";
		help(argv);
		return 0;
	}
	help(argv);
	//img0 = img0(Rect(1000, 1000, 800, 800));
	namedWindow("image", WINDOW_NORMAL);
	img0.copyTo(img);
	cvtColor(img, markerMask, COLOR_BGR2GRAY);
	cvtColor(markerMask, imgGray, COLOR_GRAY2BGR);
	markerMask = Scalar::all(0);
	imshow("image", img);
	setMouseCallback("image", onMouse, 0);
	for (;;)
	{
		char c = (char)waitKey(0);
		if (c == 27)
			break;
		if (c == 'r')
		{
			markerMask = Scalar::all(0);
			img0.copyTo(img);
			namedWindow("image", WINDOW_NORMAL);
			imshow("image", img);
		}
		if (c == 'w' || c == ' ')
		{
			//對(duì)繪制完成的圖像進(jìn)行下一步操作
			//須在鍵入相應(yīng)按鍵后執(zhí)行
		}
	}
	return 0;
}

到此這篇關(guān)于Opencv實(shí)現(xiàn)鼠標(biāo)事件與窗口互動(dòng)功能過(guò)程的文章就介紹到這了,更多相關(guān)Opencv鼠標(biāo)事件與窗口互動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python 30行代碼實(shí)現(xiàn)螞蟻森林自動(dòng)偷能量

    python 30行代碼實(shí)現(xiàn)螞蟻森林自動(dòng)偷能量

    這篇文章主要介紹了python 30行代碼實(shí)現(xiàn)螞蟻森林自動(dòng)偷能量的方法,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-02-02
  • Python中pickle模塊的使用詳解

    Python中pickle模塊的使用詳解

    這篇文章主要介紹了Python中pickle模塊的使用詳解,python的pickle模塊提供了一個(gè)簡(jiǎn)答的持久化功能,可以將對(duì)象以文件的形式存放在磁盤上,pickle模塊實(shí)現(xiàn)了基本的數(shù)據(jù)序列化和反序列化,需要的朋友可以參考下
    2023-08-08
  • python 畫(huà)3維軌跡圖并進(jìn)行比較的實(shí)例

    python 畫(huà)3維軌跡圖并進(jìn)行比較的實(shí)例

    今天小編就為大家分享一篇python 畫(huà)3維軌跡圖并進(jìn)行比較的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • Python2實(shí)現(xiàn)的LED大數(shù)字顯示效果示例

    Python2實(shí)現(xiàn)的LED大數(shù)字顯示效果示例

    這篇文章主要介紹了Python2實(shí)現(xiàn)的LED大數(shù)字顯示效果,涉及Python的簡(jiǎn)單交互與列表相關(guān)使用技巧,需要的朋友可以參考下
    2017-09-09
  • python畫(huà)圖--輸出指定像素點(diǎn)的顏色值方法

    python畫(huà)圖--輸出指定像素點(diǎn)的顏色值方法

    今天小編就為大家分享一篇python畫(huà)圖--輸出指定像素點(diǎn)的顏色值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • Python?pandas?DataFrame基礎(chǔ)運(yùn)算及空值填充詳解

    Python?pandas?DataFrame基礎(chǔ)運(yùn)算及空值填充詳解

    pandas除了可以drop含有空值的數(shù)據(jù)之外,當(dāng)然也可以用來(lái)填充空值,下面這篇文章主要給大家介紹了關(guān)于Python?pandas?DataFrame基礎(chǔ)運(yùn)算及空值填充的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • pandas之分組groupby()的使用整理與總結(jié)

    pandas之分組groupby()的使用整理與總結(jié)

    這篇文章主要介紹了pandas之分組groupby()的使用整理與總結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Python實(shí)用庫(kù) PrettyTable 學(xué)習(xí)筆記

    Python實(shí)用庫(kù) PrettyTable 學(xué)習(xí)筆記

    這篇文章主要介紹了Python實(shí)用庫(kù) PrettyTable 學(xué)習(xí)筆記,結(jié)合實(shí)例形式分析了Python表格操作庫(kù)PrettyTable的安裝、使用技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2019-08-08
  • 如何基于Python爬蟲(chóng)爬取美團(tuán)酒店信息

    如何基于Python爬蟲(chóng)爬取美團(tuán)酒店信息

    這篇文章主要介紹了如何基于Python爬蟲(chóng)爬取美團(tuán)酒店信息,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Python+Selenium實(shí)現(xiàn)短視頻自動(dòng)上傳與發(fā)布的實(shí)踐

    Python+Selenium實(shí)現(xiàn)短視頻自動(dòng)上傳與發(fā)布的實(shí)踐

    本文主要介紹了Python+Selenium實(shí)現(xiàn)短視頻自動(dòng)上傳與發(fā)布的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04

最新評(píng)論