关于easypr中闭运算内核大小的选取

easypr中,选用HSV颜色进行车牌定位,在H、S、V范围内的像素点置为255,其余0,随后进行闭运算,扩大车牌连通域。

在闭运算中,内核大小选取十分重要,源码中选取10,2作为内核大小,这是为什么呢?

车牌长宽比大致5:1,但是内核大小为什么不用5,1呢,太小,形不成大的连通域,看下图:

void colorMatch(const Color r) 
{
	// if use adaptive_minsv
	// min value of s and v is adaptive to h
	const float max_sv = 255;
	const float minref_sv = 64;

	const float minabs_sv = 95; //95;

	// H range of blue 

	const int min_blue = 100;  // 100
	const int max_blue = 140;  // 140

	// H range of yellow

	const int min_yellow = 15;  // 15
	const int max_yellow = 40;  // 40

	// H range of white

	const int min_white = 0;   // 15
	const int max_white = 30;  // 40

	Mat src,src_hsv;

	src = imread("car6.jpg", 1);
	// convert to HSV space
	cvtColor(src, src_hsv, CV_BGR2HSV);

	std::vector<cv::Mat> hsvSplit;
	split(src_hsv, hsvSplit);
	equalizeHist(hsvSplit[2], hsvSplit[2]);
	merge(hsvSplit, src_hsv);


	int min_h = 0;
	int max_h = 0;
	switch (r) {
	case BLUE:
		min_h = min_blue;
		max_h = max_blue;
		break;
	case YELLOW:
		min_h = min_yellow;
		max_h = max_yellow;
		break;
	case WHITE:
		min_h = min_white;
		max_h = max_white;
		break;
	default:
		// Color::UNKNOWN
		break;
	}
	float diff_h = float((max_h - min_h) / 2);
	float avg_h = min_h + diff_h;

	int channels = src_hsv.channels();
	int nRows = src_hsv.rows;

	// consider multi channel image
	int nCols = src_hsv.cols * channels;
	if (src_hsv.isContinuous()) {
		nCols *= nRows;
		nRows = 1;
	}
	int i, j;
	uchar* p;
	float s_all = 0;
	float v_all = 0;
	float count = 0;
	for (i = 0; i < nRows; ++i) {
		p = src_hsv.ptr<uchar>(i);
		for (j = 0; j < nCols; j += 3) {
			int H = int(p[j]);      // 0-180
			int S = int(p[j + 1]);  // 0-255
			int V = int(p[j + 2]);  // 0-255

			s_all += S;
			v_all += V;
			count++;

			bool colorMatched = false;

			if (H > min_h && H < max_h) {
				float Hdiff = 0;
				if (H > avg_h)
					Hdiff = H - avg_h;
				else
					Hdiff = avg_h - H;

				float Hdiff_p = float(Hdiff) / diff_h;

				float min_sv = 0;
				if (1)//颜色正,最小值可以到1/2,不正,最小值为1
					min_sv =
					minref_sv -
					minref_sv / 2 *
					(1
						- Hdiff_p);  // inref_sv - minref_sv / 2 * (1 - Hdiff_p)
				else
					min_sv = minabs_sv;  // add

				if ((S > min_sv && S < max_sv) && (V > min_sv && V < max_sv))
					colorMatched = true;
			}

			if (colorMatched == true) {
				p[j] = 0;
				p[j + 1] = 0;
				p[j + 2] = 255;
			}
			else {
				p[j] = 0;
				p[j + 1] = 0;
				p[j + 2] = 0;
			}
		}
	}
	Mat src_grey,match;
	std::vector<cv::Mat> hsvSplit_done;
	split(src_hsv, hsvSplit_done);
	src_grey = hsvSplit_done[2];

	//imshow("src_grey", src_grey);
	match = src_grey;
	//imshow("match", match);

	Mat src_threshold;//此步骤进行不进行好像没有区别
	threshold(match, src_threshold, 0, 255,
		CV_THRESH_OTSU + CV_THRESH_BINARY);
	imshow("src_threshold", src_threshold);

	Mat img1, img2;
	Mat element = getStructuringElement(MORPH_RECT, Size(10, 2));//内核 车牌的长宽比大约 5:1,这样可以方便提取车牌,10:2比5:1可以形成更大的连通域
	morphologyEx(src_threshold, img1, MORPH_CLOSE, element);//闭运算

	imshow("img1", img1);
 }

原图:

HSV匹配后:

 内核10,2:

 内核5,1:

内核20,4:

 内核20,4时,效果更好,但是不一定适用于其他车牌不明显的场景(距离摄像头过远),拍得车牌很小。

综合考虑,选用10,2.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值