* add nms algorithm for 1D array

* add project algorithm for character segment
v1.6alpha
liuruoze 8 years ago
parent a366a0b950
commit 14384a81f0

@ -98,8 +98,8 @@ private:\
kDebug = param
// Display the image.
#define SHOW_IMAGE(imgName) \
if (kDebug) { \
#define SHOW_IMAGE(imgName, debug) \
if (debug) { \
imshow("imgName", imgName); \
waitKey(0); \
destroyWindow("imgName"); \

@ -5,6 +5,7 @@
#include "easypr/config.h"
using namespace cv;
using namespace std;
namespace easypr {
@ -17,6 +18,9 @@ class CCharsSegment {
//! using project the segment chars in plate
int charsSegmentUsingProject(Mat input, std::vector<Mat>& resultVec, std::vector<Mat>& grayChars, Color color = BLUE);
//! using project
int projectSegment(const Mat& input, Color color, vector<int>& out_indexs);
bool verifyCharSizes(Mat r);
// find the best chinese binaranzation method

@ -116,6 +116,33 @@ Rect rectEnlarge(const Rect& src, const int mat_width, const int mat_height);
// write images to temp folder
void writeTempImage(const Mat& outImg, const string path);
//! non-maximum surpresion for 1d array
template<typename T>
void NMSfor1D(const vector<T>& arr, vector<int>& index) {
// prepare
int size = (int)arr.size();
index.resize(size);
for (int j = 0; j < size; j++)
index.at(j) = 0;
// nms
int i = 1;
while (i < size - 1) {
if (arr.at(i) > arr.at(i + 1)) {
if (arr.at(i) >= arr.at(i - 1))
index.at(i) = 1;
}
else {
while (i < size - 1 && arr.at(i) <= arr.at(i + 1))
i = i + 1;
if (i < size - 1)
index.at(i) = 1;
}
i = i + 2;
}
}
} /*! \namespace easypr*/
#endif // EASYPR_CORE_COREFUNC_H_

File diff suppressed because it is too large Load Diff

@ -2578,3 +2578,33 @@ Recall:0%, Precise:0%, Fscore:0%.
Recall:88.4994%, Precise:66.935%, Fscore:76.2213%.
0-error:59.6%, 1-error:70.4%, Chinese-precise:72.4%
总共时间: 552秒, 平均执行时间:2.15625秒
2017-04-04 17:48:01
总图片数:1, Plates count:1, 未定位车牌:0, 检出率:100%
Recall:88.2833%, Precise:88.2833%, Fscore:88.2833%.
0-error:0%, 1-error:100%, Chinese-precise:100%
总共时间: 11秒, 平均执行时间:11秒
2017-04-04 17:52:45
总图片数:1, Plates count:1, 未定位车牌:0, 检出率:100%
Recall:88.2833%, Precise:88.2833%, Fscore:88.2833%.
0-error:0%, 1-error:100%, Chinese-precise:100%
总共时间: 25秒, 平均执行时间:25秒
2017-04-04 18:17:02
总图片数:1, Plates count:1, 未定位车牌:0, 检出率:100%
Recall:88.2833%, Precise:88.2833%, Fscore:88.2833%.
0-error:0%, 1-error:100%, Chinese-precise:100%
总共时间: 23秒, 平均执行时间:23秒
2017-04-04 19:10:48
总图片数:1, Plates count:1, 未定位车牌:0, 检出率:100%
Recall:88.2833%, Precise:88.2833%, Fscore:88.2833%.
0-error:0%, 1-error:100%, Chinese-precise:100%
总共时间: 7秒, 平均执行时间:7秒
2017-04-04 19:12:13
总图片数:1, Plates count:1, 未定位车牌:0, 检出率:100%
Recall:88.2833%, Precise:88.2833%, Fscore:88.2833%.
0-error:0%, 1-error:100%, Chinese-precise:100%
总共时间: 9秒, 平均执行时间:9秒
2017-04-04 19:13:04
总图片数:1, Plates count:1, 未定位车牌:0, 检出率:100%
Recall:88.2833%, Precise:88.2833%, Fscore:88.2833%.
0-error:0%, 1-error:100%, Chinese-precise:100%
总共时间: 14秒, 平均执行时间:14秒

@ -362,49 +362,71 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
return 0;
}
int index_1 = 0;
int CCharsSegment::charsSegmentUsingProject(Mat input, vector<Mat>& resultVec, vector<Mat>& grayChars, Color color) {
int CCharsSegment::projectSegment(const Mat& input, Color color, vector<int>& out_indexs) {
if (!input.data) return 0x01;
Color plateType = color;
Mat input_grey;
cvtColor(input, input_grey, CV_BGR2GRAY);
if (0) {
imshow("plate", input_grey);
waitKey(0);
destroyWindow("plate");
}
if (1) {
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "resources/image/tmp/plateMatGray/plate_" << index_1++ << ".jpg";
imwrite(ss.str(), input_grey);
}
SHOW_IMAGE(input_grey, 0);
Mat img_threshold;
img_threshold = input_grey.clone();
spatial_ostu(img_threshold, 8, 2, plateType);
if (0) {
imshow("plate", img_threshold);
waitKey(0);
destroyWindow("plate");
}
SHOW_IMAGE(img_threshold, 0);
// remove liuding and hor lines
// also judge weather is plate use jump count
if (!clearLiuDing(img_threshold)) return 0x02;
SHOW_IMAGE(img_threshold, 0);
Mat vhist = ProjectedHistogram(img_threshold, VERTICAL, 0);
Mat showHist = showHistogram(vhist);
SHOW_IMAGE(showHist, 1);
vector<float> values;
vector<int> indexs;
int size = vhist.cols;
for (int i = 0; i < size; i++) {
float val = vhist.at<float>(i);
values.push_back(1.f - val);
}
Mat img_test = img_threshold.clone();
NMSfor1D<float>(values, indexs);
out_indexs.resize(size);
for (int j = 0; j < size; j++)
out_indexs.at(j) = 0;
for (int i = 0; i < size; i++) {
float val = vhist.at<float>(i);
if (indexs.at(i) && val < 0.1f) {
out_indexs.at(i) = 1;
for (int j = 0; j < img_test.rows; j++) {
img_test.at<char>(j, i) = (char)255;
}
}
}
SHOW_IMAGE(img_test, 1);
return 0;
}
int CCharsSegment::charsSegmentUsingProject(Mat input, vector<Mat>& resultVec, vector<Mat>& grayChars, Color color) {
if (!input.data) return 0x01;
vector<int> out_indexs;
projectSegment(input, color, out_indexs);
//Mat vhist = ProjectedHistogram(img_threshold, VERTICAL, 0);
//Mat showHist = showHistogram(vhist);
//if (0) {
// imshow("showHist", showHist);
// waitKey(0);
// destroyWindow("showHist");
//}
Color plateType = color;
Mat input_grey;
cvtColor(input, input_grey, CV_BGR2GRAY);
Mat img_threshold;
img_threshold = input_grey.clone();
spatial_ostu(img_threshold, 8, 2, plateType);
// remove liuding and hor lines, also judge weather is plate use jump count
if (!clearLiuDing(img_threshold)) return 0x02;
Mat img_contours;
img_threshold.copyTo(img_contours);
@ -417,16 +439,14 @@ int CCharsSegment::charsSegmentUsingProject(Mat input, vector<Mat>& resultVec, v
vector<vector<Point> >::iterator itc = contours.begin();
vector<Rect> vecRect;
while (itc != contours.end()) {
Rect mr = boundingRect(Mat(*itc));
Mat auxRoi(img_threshold, mr);
if (verifyCharSizes(auxRoi)) vecRect.push_back(mr);
if (verifyCharSizes(auxRoi))
vecRect.push_back(mr);
++itc;
}
if (vecRect.size() == 0) return 0x03;
vector<Rect> sortedRect(vecRect);
@ -434,7 +454,6 @@ int CCharsSegment::charsSegmentUsingProject(Mat input, vector<Mat>& resultVec, v
[](const Rect& r1, const Rect& r2) { return r1.x < r2.x; });
size_t specIndex = 0;
specIndex = GetSpecificRect(sortedRect);
Rect chineseRect;
@ -474,23 +493,17 @@ int CCharsSegment::charsSegmentUsingProject(Mat input, vector<Mat>& resultVec, v
if (!slideChineseWindow(input_grey, mr, newRoi, plateType, slideLengthRatio, useAdapThreshold))
judgeChinese(auxRoi, newRoi, plateType);
}
else
else {
judgeChinese(auxRoi, newRoi, plateType);
}
}
else {
if (BLUE == plateType) {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_BINARY + CV_THRESH_OTSU);
}
else if (YELLOW == plateType) {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_BINARY_INV + CV_THRESH_OTSU);
switch (plateType) {
case BLUE: threshold(auxRoi, newRoi, 0, 255, CV_THRESH_BINARY + CV_THRESH_OTSU); break;
case YELLOW: threshold(auxRoi, newRoi, 0, 255, CV_THRESH_BINARY_INV + CV_THRESH_OTSU); break;
case WHITE: threshold(auxRoi, newRoi, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY_INV); break;
default: threshold(auxRoi, newRoi, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY); break;
}
else if (WHITE == plateType) {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY_INV);
}
else {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
}
newRoi = preprocessChar(newRoi);
}

@ -660,7 +660,6 @@ Mat ProjectedHistogram(Mat img, int t, int threshold) {
return mhist;
}
Mat showHistogram(const Mat& hist) {
int height = 32;
int width = hist.cols;
@ -672,7 +671,6 @@ Mat showHistogram(const Mat& hist) {
show.at<char>(j, i) = (char)255;
}
}
return show;
}

@ -231,15 +231,14 @@ Mat charFeatures2(Mat in, int sizeData) {
}
void getGrayCharFeatures(const Mat& grayChar, Mat& features) {
SET_DEBUG(true);
// TODO: check channnels == 1
SHOW_IMAGE(grayChar);
SHOW_IMAGE(grayChar, 0);
// resize to uniform size, like 20x32
Mat char_mat;
char_mat.create(kGrayCharHeight, kGrayCharWidth, CV_32FC1);
resize(grayChar, char_mat, char_mat.size(), 0, 0, INTER_LINEAR);
SHOW_IMAGE(char_mat);
SHOW_IMAGE(char_mat, 0);
// convert to float
bool useConvert = false;
@ -247,19 +246,19 @@ void getGrayCharFeatures(const Mat& grayChar, Mat& features) {
Mat float_img;
float scale = 1.f / 255;
char_mat.convertTo(float_img, CV_32FC1, scale, 0);
SHOW_IMAGE(float_img);
SHOW_IMAGE(float_img, 0);
}
// cut from mean, it can be optional
bool useMean = true;
if (useMean) {
char_mat -= mean(char_mat);
SHOW_IMAGE(char_mat);
SHOW_IMAGE(char_mat, 0);
}
// use lbp to get features, it can be changed to other
Mat lbpimage = libfacerec::olbp(char_mat);
SHOW_IMAGE(lbpimage);
SHOW_IMAGE(lbpimage, 0);
Mat lbp_hist = libfacerec::spatial_histogram(lbpimage, 32, 4, 4);

@ -101,7 +101,7 @@ namespace easypr {
// parameters
const bool filesNatureSort = true;
const int max_plates = 4;
const int max_plates = 1;
const int isGenerateGT = 1;
// set the parameters of CPlateRecognize

Loading…
Cancel
Save