بهبود تصویر در شناسایی اثر انگشت - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

بهبود تصویر در شناسایی اثر انگشت

+1 امتیاز

سلام.

برای بهبود تصاویر اثر انگشت چه فیلتری باید اعمال کنیم من هر فیلتر آستانه گیری اعمال می کنم به جواب درستی نمی رسم.

سوال شده خرداد 20, 1394  بوسیله ی ابید (امتیاز 781)   19 89 106

1 پاسخ

+3 امتیاز
 
بهترین پاسخ

با فیلتر گابور براحتی می تونید آستانه گیری مناسبی برروی تصویر فوق انجام بدید.

cv::Mat getRealGaborKernel(const cv::Size& k_size, float sigma, float theta, float nu, float gamma){
		float  sigma_x = sigma;
		float  sigma_y = sigma / gamma;
		
		int     nstds = 3;
		float  k_max = float(CV_PI / 2);
		float  f = (float)cv::sqrt(2.0);

		int x_min, x_max, y_min, y_max;
		
		float c = (float)cos(theta);
		float s = (float)sin(theta);

		if (k_size.width > 0)
			x_max = k_size.width / 2;
		else x_max = cvRound(std::max(fabs(nstds * sigma_x * c), fabs(nstds * sigma_y * s)));

		if (k_size.height > 0)
			y_max = k_size.height / 2;
		else y_max = cvRound(std::max(fabs(nstds * sigma_x * s), fabs(nstds * sigma_y * c)));

		x_min = -x_max;
		y_min = -y_max;

		
		cv::Mat kernel(y_max - y_min + 1, x_max - x_min + 1, CV_32FC1);

		float k = k_max / pow(f, nu);
		float exy = sigma_x * sigma_y / 2;
		float scale_real = k * k / sigma_x / sigma_y;

		int    x, y;
		for (y = y_min; y <= y_max; y++){
			float* row = kernel.ptr<float>(y_max - y);
			for (x = x_min; x <= x_max; x++){
				float xr = x * c + y * s;
				float v = scale_real * exp(-(x * x + y * y) * scale_real / 2);
				float temp = cos(k * xr) - exp(-exy);
				v = temp * v;
				row[x_max - x] = v;
			}
		}
		return kernel;
	}

cv::Mat getMinMaxImage(cv::InputArray _src_min, cv::InputArray _src_max, float thresh) {
		cv::Mat src_min = _src_min.getMat();
		cv::Mat src_max = _src_max.getMat();


		cv::Mat src_min_abs = cv::abs(src_min);
		cv::Mat result = src_max.clone();
		result.setTo(-1);

		for (size_t i = 0; i < result.rows; i++) {
			float* row_min = src_min.ptr<float>(i);
			float* row_max = src_max.ptr<float>(i);
			float* row_min_abs = src_min_abs.ptr<float>(i);
			float* row_result = result.ptr<float>(i);

			for (size_t j = 0; j < result.cols; j++)
				if (row_min_abs[j] > row_max[j]) {
					if (row_min_abs[j] > thresh)
						row_result[j] = row_min[j];
				}
				else {
					if (row_max[j] > thresh)
						row_result[j] = row_max[j];
				}
		}
		return result;
	}
void gaborFilter(cv::InputArray _src, cv::InputOutputArray _dst,int angles_count, int b_size,float thresh){
		cv::Mat src = _src.getMat();

		cv::Mat src_float;
		normalize(src, src_float, 1, 0, CV_MINMAX, CV_32F);
		
		std::vector<int> sizes = { b_size };

		cv::Mat min_img, max_img;
		for (int k = 0; k < sizes.size(); k++)
		for (int i = 0; i < angles_count - 0; i += 2){

			for (float j = 0.5f; j <= 2.5f; j += 1.f){
				cv::Mat kernel = getRealGaborKernel(Size(sizes[k], sizes[k]), CV_PI * 1, i*CV_PI / angles_count + CV_PI / 2, j, 0.9);
				

				cv::Mat dst;
				cv::filter2D(src_float, dst, CV_32F, kernel, cv::Point( -1, -1), 0, BORDER_REPLICATE);

				updateMinMaxImages(dst, min_img, max_img);

			}
		}
		const float t = 0.001f;
		auto result = getMinMaxImage(min_img, max_img, thresh);

		
		cv::normalize(result, _dst, 0, 255,cv::NORM_MINMAX, CV_8UC1);
		

	}
	void gaborFilterBinary(cv::InputArray _src, cv::InputOutputArray _dst, int angles_count, int b_size,float thresh){
		gaborFilter(_src, _dst,angles_count,b_size,thresh);
		adaptiveThreshold(_dst, _dst, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 35, 4);
	}

به صورت زیر هم تستش کنید.

std::string file_name = R"(img.jpg)";
	cv::Mat img = cv::imread(file_name, 0);

	cv::Mat dst;
	gaborFilterBinary(img, dst,30,19);
	imshow("dst", dst);
	cv::waitKey(0);

خروجی :

گابور اثرانگشت

پاسخ داده شده خرداد 24, 1396 بوسیله ی مصطفی ساتکی (امتیاز 21,998)   24 34 75
انتخاب شد خرداد 25, 1396 بوسیله ی ابید
ممنون .تو این مثالی که قرار دادید اندازه کرنل را 9 و تعداد زوایا را 30 در نظر گرفتید این مقادیر چطور محاسبه شده؟
...