【图像处理】selectROI实现

摘要:
selectROI在opencv中处于tracking模块,需要opencv_contrib。
由于扣选目标区域在跟踪时候应用较广泛,当没有安装opencv_contrib扩展包时,需要自身去实现该功能。
本文基于c++和python分别实现。可以从左上角往右下角画roi,或者从右下角往左上角画roi。
其中:

  1. c++代码包括selectROI.h, selectROI.cpp, main.cpp;
  2. python代码用了大量全局变量,有待改进。

基于c++和opencv实现的selectROI:

selectROI.h

#pragma once
#ifndef _SELECT_ROI_H_HH
#define _SELECT_ROI_H_HH

#include <opencv2/opencv.hpp>

typedef struct selectROI_handler_param {
	cv::Point click_1, click_2, click_move;
	bool drawRoi;
	bool endDraw;
}selectROI_handler_param;

class selectROI_handler
{
	friend class selectROI;
protected:
	static void onMouse(int event, int x, int y, int flags, void* param);
};

class selectROI {
public:
	selectROI();
	virtual ~selectROI();
public:
	void init_param();
	cv::Rect add(const std::string windname, const cv::Mat& image);
	void exit();
private:
	selectROI_handler_param* param;
};
#endif

selectROI.cpp

#include "selectROI.h"

selectROI::selectROI()
{
}

selectROI::~selectROI()
{
}

void selectROI_handler::onMouse(int event, int x, int y, int flags, void* param)
{
	selectROI_handler_param* shparam = (selectROI_handler_param*)param;
	switch (event)
	{
	case CV_EVENT_LBUTTONDOWN:
		shparam->drawRoi = true;
		shparam->click_1.x = x;
		shparam->click_1.y = y;
		break;
	case CV_EVENT_MOUSEMOVE:
		shparam->click_move.x = x;
		shparam->click_move.y = y;
		break;
	case CV_EVENT_LBUTTONUP:
		shparam->click_2.x = x;
		shparam->click_2.y = y;
		shparam->drawRoi = false;
		shparam->endDraw = true;
		break;
	default:
		break;
	}
}

cv::Rect selectROI::add(const std::string windname, const cv::Mat& image)
{
	cv::Mat src_copy = image.clone();
	cv::imshow(windname, src_copy);
	int lx, ly, w, h;
	while (!param->endDraw)
	{
		cv::setMouseCallback(windname, selectROI_handler::onMouse, param);
		src_copy = image.clone();
		cv::Rect temp;
		if (param->drawRoi)
		{		
			lx = param->click_1.x > param->click_move.x ? param->click_move.x : param->click_1.x;
			ly = param->click_1.y > param->click_move.y ? param->click_move.y : param->click_1.y;
			w = std::abs(param->click_move.x - param->click_1.x);
			h = std::abs(param->click_move.y - param->click_1.y);
			temp = cv::Rect(lx, ly, w, h);
			cv::rectangle(src_copy, temp, cv::Scalar(255,255,255));
		}
		cv::imshow(windname, src_copy);
		cv::waitKey(20);
	}
	lx = param->click_1.x > param->click_2.x ? param->click_2.x : param->click_1.x;
	ly = param->click_1.y > param->click_2.y ? param->click_2.y : param->click_1.y;
	w = std::abs(param->click_2.x - param->click_1.x);
	h = std::abs(param->click_2.y - param->click_1.y);
	cv::Rect res = cv::Rect(lx, ly, w, h);
	return res;
}

void selectROI::init_param()
{
	param = new selectROI_handler_param();
	memset(param, 0, sizeof(selectROI_handler_param));
	param->drawRoi = false;
	param->endDraw = false;
}

void selectROI::exit()
{
	delete param;
}

main.cpp

#include "selectROI.h"

int main()
{
	cv::Mat src = cv::imread("aero3.jpg");
	selectROI sRoi;
	sRoi.init_param();
	cv::Rect roi = sRoi.add("selectRoi.jpg", src);
	cv::rectangle(src, roi, cv::Scalar(255, 0, 0));
	cv::imshow("selectRoi.jpg", src);
	cv::waitKey(0);
	sRoi.exit();
	return 0;
}

基于python和opencv实现的selectROI

selectROI.py

#--coding--utf8
import cv2 as cv

click_1_x = 0
click_1_y = 0
click_2_x = 0
click_2_y = 0
click_m_x = 0
click_m_y = 0
endDraw = False
drawRoi = False

def lbuttonDown(x):
	global drawRoi
	global click_1_x
	global click_1_y
	click_1_x = x[0]
	click_1_y = x[1]
	drawRoi = True
def mouseMove(x):
	global drawRoi
	global click_m_x
	global click_m_y
	if drawRoi == True:
		click_m_x = x[0]
		click_m_y = x[1]
def lbuttonUp(x):
	global drawRoi
	global endDraw
	global click_2_x
	global click_2_y
	if drawRoi == True:
		click_2_x = x[0]
		click_2_y = x[1]
		drawRoi = False
		endDraw = True

MouseHandler = {
	cv.EVENT_LBUTTONDOWN: lbuttonDown,
	cv.EVENT_MOUSEMOVE: mouseMove,
	cv.EVENT_LBUTTONUP: lbuttonUp
}
def onMouse(event, x, y, flags, param):
	t = (x,y)
	MouseHandler[event](t)

def add_selectROI(windowName, image):
	global endDraw
	global drawRoi
	global click_m_x
	global click_m_y
	global click_1_x
	global click_1_y
	global click_2_x
	global click_2_y
	src_copy = image.copy()
	cv.imshow(windowName, src_copy)
	while endDraw == False:
			if endDraw == True:
				break
			cv.setMouseCallback(windowName, onMouse)
			src_copy = image.copy()
			if drawRoi == True:
				cv.rectangle(src_copy, (click_1_x, click_1_y), (click_m_x, click_m_y), (255,255,255))
			cv.imshow(windowName, src_copy)
			cv.waitKey(20)
	return click_1_x,click_1_y,click_2_x,click_2_y

def main():
	src = cv.imread('aero3.jpg')
	lx,ly,rx,ry = add_selectROI('selectRoi.jpg', src)
	cv.rectangle(src, (lx, ly), (rx, ry), (255,0,0))
	cv.imshow('selectRoi.jpg', src)
	cv.waitKey(0)

if __name__ == "__main__":
	main()
发布了35 篇原创文章 · 获赞 13 · 访问量 6307

猜你喜欢

转载自blog.csdn.net/qq_35306281/article/details/104271742