Multiple Template Matching opencv - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

Multiple Template Matching opencv

0 امتیاز
46 بازدید

سلام دوستان . میخوام از روی یه الگو تصویر رو پیمایش کنم و تمپلیتم رو توو تصویر پیدا کنم . ولی چون زاویه تصویر تملپیتم عوض میشه (یه توپ در حال چرخش و چون سرعت بالاست یکم به صورت خط نشون داده میشه واسه همون زاویه تغییر میکنه) فقط با یک تمپلیت نمیشه . از چند تمپلیت استفاده کردم و کد میتونه پیدا کنه ولی مشکلی که اینجاست تمپلیت های دیگه هم به صورت اشتباه توو خروجی نشون داده میشه . چطور میتونم فقط مورد صحیح رو خروجی بگیرم ؟

فقط بگم که تازه پردازش تصویر شروع کردم اگه بشه یکم واضح توضیح بدید یا قطعه کد باشه که ممنون میشم

با تشکر

کد :

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

bool FindTemplate(Mat Img_Scene_Bgr, Mat Img_Template_Bgr, Point &Point_TemplateLocation)
{
	// `Img_Scene_Bgr` and `Img_Template_Bgr` are the reference and template image
	cv::Mat Img_Result_Float(Img_Scene_Bgr.rows - Img_Template_Bgr.rows + 1, Img_Scene_Bgr.cols - Img_Template_Bgr.cols + 1, CV_32FC1);
	cv::matchTemplate(Img_Template_Bgr, Img_Scene_Bgr, Img_Result_Float, CV_TM_CCOEFF_NORMED);
	normalize(Img_Result_Float, Img_Result_Float, 0, 1, NORM_MINMAX, -1, Mat());

	double minval, maxval, threshold = 0.7;
	cv::Point minloc, maxloc;
	cv::minMaxLoc(Img_Result_Float, &minval, &maxval, &minloc, &maxloc);

	if (maxval >= threshold)
	{
		Point_TemplateLocation = maxloc;
		return true;
	}
	else
	{
		return false;
	}
}

int main(int argc, char** argv)
{
	Mat Img_Scene;
	Mat Img_Template_1;
	Mat Img_Template_2;
	Mat Img_Template_3;
	Mat Img_Result;
	char* image_window = "Source Image";
	char* result_window = "Result window";
	/// Load image and template
	Img_Scene = imread("1.png", 1);
	Img_Template_1 = imread("ball3.png", 1);
	Img_Template_2 = imread("ball2.png", 1);
	Img_Template_3 = imread("ball4.png", 1);

	if (Img_Scene.data == NULL || Img_Template_1.data == NULL || Img_Template_2.data == NULL)
	{
		cout << "Image Not Found";
		return 0;
	}

	Img_Result = Img_Scene.clone();
	vector<Mat> List_Template_Img;
	List_Template_Img.push_back(Img_Template_1);//Otherwise Get some folder & add the Files in it
	List_Template_Img.push_back(Img_Template_2);
	List_Template_Img.push_back(Img_Template_3);

	Point  Point_TemplateLocation;
	for (int i = 0; i < List_Template_Img.size(); i++)
	{
		if (!FindTemplate(Img_Scene, List_Template_Img[i], Point_TemplateLocation))
		{
			cout << "No Match Found";
		}
		/// Show me what you got
		rectangle(Img_Result, Point_TemplateLocation, Point(Point_TemplateLocation.x + Img_Template_1.cols, Point_TemplateLocation.y + Img_Template_1.rows), Scalar(0, 0, 255), 2, 8, 0);
		putText(Img_Result, format("Object %d ", i), Point(Point_TemplateLocation.x + Img_Template_1.cols / 4, Point_TemplateLocation.y + Img_Template_1.rows / 2), 1, 1, Scalar(255, 0, 0), 1, -1);
	}
	/// Create windows
	namedWindow(image_window, CV_WINDOW_AUTOSIZE);
	namedWindow(result_window, CV_WINDOW_AUTOSIZE);

	imshow(image_window, Img_Template_1);
	imshow(image_window, Img_Template_2);
	imshow(result_window, Img_Result);

	waitKey(0);
	return 0;
}

 

 

تصویر خروجی :

 

 

سوال شده آبان 19  بوسیله ی manu (امتیاز 15)   1
لطفاً مشخص کنید که آیا تصاویر شما به صورت فریم ها متوالی هست یا نه؟

3 پاسخ

+1 امتیاز
تصویر شما حداقل تو این اسنپشاتی که قرار دادید کیفیت مناسب را نداره به نظرم هم رزولوشن و هم fps را ارتقاء بدید .به نظرم ابتدا حداقل ها را فراهم کنید و بعد به دنبال یک روش مناسب باشید.
پاسخ داده شده آبان 20 بوسیله ی عباس مولایی (امتیاز 290)   4
ممنون ولی کیفیت همینه . راه حل دیگه ای به غیر از template matching سراغ ندارین؟
چند نمونه تصویر دیگر در اینجا قرار بدید ببینم میشه ایده مناسبی داد.
دو تا اضافه کردم . همش عین هم ه فقط همون توپ سفید رنگ نقاط مختلفی ه با همون کیفیت
0 امتیاز
از الگوهای تطبیق پذیر با استفاده از توابع انرژی استفاده کنید، هر کجا گرادیان کمینه شد بیشترین میزان تطبیق را دارید، همچنین استفاده از افین ترنسفورم هم کمک میکنه که تغییر زاویه و شکل تاثیری ایجاد نکنه.
پاسخ داده شده آبان 20 بوسیله ی Behzadjoukar (امتیاز 13)  
میشه یکم بیشتر توضیح بدین؟
0 امتیاز

من با background subtraction تونستم به اون وضوح که میخوام برسم و با تمپلیت مچینگ میشه راحت گرفت درصورتی که وسط دایره رو سیاه کنم . چطور میتونم این کارو بکنم؟

پاسخ داده شده آبان 22 بوسیله ی manu (امتیاز 15)   1
تصویر را smooth کنید تا جائیکه میشه نویزها از بین بره و سپس با findcontour کانتور بزرگ میانی را پیدا و با drawContour حذفش کنید.

ممنون از دوستان . با subtract تونستم اون قسمت رو حذف کنم و مشکل اصلی حل شد

فقط یه سوال موند یه قسمت از صفحه هست که اصلا توپ تووش دیده نمیشه وقتی توو اون حالت از تمپلیت مچینگ استفاده میکنم میاد به اشتباه حتی یه نقطه سفید میبینه فکر میکنه شی مورد نظر منه چطور میتونم اینو حل کنم ؟

خیلی خوب و دقیق کار میکنه .  فقط دوربین طوری قرار گرفته که حدود یک پنجم از صفحه که توپ از اون رد میشه دیده نمیشه توو این حالت برنامه خطا میکنه

نمیشه مثلا واسش درصد تطبیق گذاشت؟ مثلا اگه بیشتر از 50 درصد با تمپلیت من مچ بود موقعیت رو نشون بده در غیر این صورت  نشون نده

 

...