Example #1
0
float Index::getKeyPointOrientation(const Mat& image, const KeyPoint &pnt)
{
    int half_k = ROTATION_PATCH_SIZE/2;
    Point2f pt = pnt.pt;
    
    int m_01 = 0, m_10 = 0;
    
    const uchar* center = image.ptr<uchar> (cvRound(pt.y), cvRound(pt.x));
    
    // Treat the center line differently, v=0
    for (int u = -half_k; u <= half_k; ++u)
        m_10 += u * center[u];
    
    // Go line by line in the circular patch
    int step = (int)image.step1();
    for (int v = 1; v <= half_k; ++v)
    {
        // Proceed over the two lines
        int v_sum = 0;
        int d = u_max[v];
        for (int u = -d; u <= d; ++u)
        {
            int val_plus = center[u + v*step], val_minus = center[u - v*step];
            v_sum += (val_plus - val_minus);
            m_10 += u * (val_plus + val_minus);
        }
        m_01 += v * v_sum;
    }
    
    return fastAtan2((float)m_01, (float)m_10);
}
Example #2
0
  float IC_Angle(const Mat& image, const int half_k, Point2f pt,
		 const vector<int> & u_max)
  {
    int m_01 = 0, m_10 = 0;
    
    const uchar* center = &image.at<uchar> (cvRound(pt.y), cvRound(pt.x));
    // Treat the center line differently, v=0                                                                                                               
    for (int u = -half_k; u <= half_k; ++u)
      m_10 += u * center[u];
    
    // Go line by line in the circular patch                                                                                                                
    int step = (int)image.step1();
    for (int v = 1; v <= half_k; ++v)
      {
	// Proceed over the two lines                                                                                                                       
	int v_sum = 0;
	int d = u_max[v];
	for (int u = -d; u <= d; ++u)
	  {
            int val_plus = center[u + v*step], val_minus = center[u - v*step];
            v_sum += (val_plus - val_minus);
            m_10 += u * (val_plus + val_minus);
	  }
        m_01 += v * v_sum;
      }
    
    return fastAtan2((float)m_01, (float)m_10);
  }
Example #3
0
/*step的方式遍历*/
void sharpen2(const Mat &image, Mat &result) 
{
	result.create(image.size(), image.type()); // allocate if necessary

	int step= image.step1();
	const uchar* previous= image.data;		// ptr to previous row
	const uchar* current=  image.data+step; // ptr to current row
	const uchar* next= image.data+2*step;   // ptr to next row
	uchar *output= result.data+step;		// ptr to output row

	for (int j= 1; j<image.rows-1; j++) { // for each row (except first and last)
		for (int i=1; i<image.cols-1; i++) { // for each column (except first and last)

			output[i]= saturate_cast<uchar>(5*current[i]-current[i-1]-current[i+1]-previous[i]-next[i]); 
		}

		previous+= step;
		current+= step;
		next+= step;
		output+= step;
	}

	// Set the unprocess pixels to 0
	result.row(0).setTo(cv::Scalar(0));
	result.row(result.rows-1).setTo(cv::Scalar(0));
	result.col(0).setTo(cv::Scalar(0));
	result.col(result.cols-1).setTo(cv::Scalar(0));
}
Example #4
0
string OCR::getText(Mat src, Rect mask)
{
	if (!src.data)
	{
		cerr << "getText: No image data!" << endl;
		return string("");
	}

	// tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();

	// if (api -> Init(NULL, "eng2+fra+ita+deu"))
	// {
	// 	fprintf(stderr, "Could not initialize tesseract.\n");
	// 	exit(-1);
	// }

	Mat dst;
	preprocess(src, dst, mask);

	api -> SetImage((uchar*)dst.data, dst.size().width, dst.size().height, 
		dst.channels(), dst.step1());
	
	//Get OCR result
	char *outText = api -> GetUTF8Text();
	string text = outText;

	// api -> End();
	delete [] outText;
	//pixDestroy(&image);
	return text;
}
Example #5
0
void
homogeneousToEuclidean(const Mat & _X, Mat & _x)
{
    int d = _X.rows - 1;

    const Mat_<T> & X_rows = _X.rowRange(0,d);
    const Mat_<T> h = _X.row(d);

    const T * h_ptr = h[0], *h_ptr_end = h_ptr + h.cols;
    const T * X_ptr = X_rows[0];
    T * x_ptr = _x.ptr<T>(0);
    for (; h_ptr != h_ptr_end; ++h_ptr, ++X_ptr, ++x_ptr)
    {
        const T * X_col_ptr = X_ptr;
        T * x_col_ptr = x_ptr, *x_col_ptr_end = x_col_ptr + d * _x.step1();
        for (; x_col_ptr != x_col_ptr_end; X_col_ptr+=X_rows.step1(), x_col_ptr+=_x.step1() )
            *x_col_ptr = (*X_col_ptr) / (*h_ptr);
    }
}
Example #6
0
blok::blok(Mat input_block, int _size){
	//content = vector<unsigned int>(size,0);
	unsigned char *input = (unsigned char*)(input_block.data);
	for(int i=0;i<size;i++)
		for(int j=0;j<size;j++)
		content.push_back(input[input_block.step1()*i+j]); 
	weight=1;
	size=_size;
	licznik =0;
}
Example #7
0
void ImageWindow::showImage(Mat im)
{
    Mat rgb;
    if (im.channels()==3)
        cvtColor(im, rgb, CV_BGR2RGB);
    else
        cvtColor(im, rgb, CV_GRAY2RGB);
    QImage imQ((const uchar*)rgb.data, rgb.cols, rgb.rows, rgb.step1(), QImage::Format_RGB888);
    this->setPixmap(QPixmap::fromImage(imQ));
}
Example #8
0
static void CentroidOrientationICAngles(const Mat& img,
                                        const std::vector<cv::Point2d>& pts,
                                        const std::vector<int> & u_max,
                                        int half_k,
                                        std::vector<float> & angles)
{
    assert(img.channels() == 1);
    assert(img.type() == CV_8UC1);
    
    int step = (int)img.step1();
    angles.resize(pts.size());
    
    for(size_t ptidx = 0; ptidx < pts.size(); ptidx++ )
    {
    //    const Rect& layer = layerinfo[pts[ptidx].octave];
    //    const uchar* center = &img.at<uchar>(cvRound(pts[ptidx].pt.y) + layer.y, cvRound(pts[ptidx].pt.x) + layer.x);
        int y = cvRound(pts[ptidx].y);
        int x = cvRound(pts[ptidx].x);
        if (x <= half_k || x + half_k >= img.cols ||
            y <= half_k || y + half_k >= img.rows)
        {
            angles[ptidx] = 0.0f; // out of boundary samples
            continue;
        }
                        
        const uchar* center = &img.at<uchar>(y, x);
        int m_01 = 0, m_10 = 0;
        
        // Treat the center line differently, v=0
        for (int u = -half_k; u <= half_k; ++u){
            m_10 += u * center[u];
        }
        
        // Go line by line in the circular patch
        for (int v = 1; v <= half_k; ++v)
        {
            // Proceed over the two lines
            int v_sum = 0;
            int d = u_max[v];
            for (int u = -d; u <= d; ++u)
            {
                int val_plus = center[u + v*step], val_minus = center[u - v*step];
                v_sum += (val_plus - val_minus);
                m_10 += u * (val_plus + val_minus);
            }
            m_01 += v * v_sum;
        }
        angles[ptidx] = cv::fastAtan2((float)m_01, (float)m_10);
    }
}
Example #9
0
void	fconv_SSE( const Mat &A, const Mat &F, Mat &R )
{
	int		RowA = A.rows, ColA = A.cols, NumFeatures = A.channels();
	int		RowF = F.rows, ColF = F.cols, ChnF = F.channels();
	if( NumFeatures!=ChnF || (NumFeatures%4) )
		throw runtime_error("");
	int loop = NumFeatures / 4;

	int		RowR = RowA - RowF + 1, ColR = ColA - ColF + 1;

	float *R_src0 = (float*)R.data;
	int Rstep = R.step1();

	const float	 *F_src = F.ptr<float>(0,0);
	const float	 *A_src0 = A.ptr<float>(0,0);

	__m128 a,b,c;
	for( int rr=0; rr<RowR; rr++ ){
		const float *A_src1 = A_src0 + rr*A.cols*NumFeatures; // start addr of A.row(rr)
		float *R_scr1 = R_src0 + rr*Rstep; // start addr of R.row(rr)
		for( int cc=0; cc<ColR; cc++ ){
			const float *A_src= A_src1 + cc*NumFeatures;// A.ptr<float>(rr,cc);			
			float *R_src = R_scr1 + cc;
			// An acceleration trick of using SSE programming >>>
			__m128 v = _mm_setzero_ps();
			const float *B_off = F_src;
			for( int rp=0; rp<RowF; rp++ ){
				const float *A_off = A_src + rp*A.cols*NumFeatures;
				for( int cp=0; cp<ColF; cp++ ){
					for( int l=0; l<loop; l++ ){
						a = _mm_load_ps(A_off);
						b = _mm_load_ps(B_off);
						c = _mm_mul_ps(a, b);
						v = _mm_add_ps(v, c);
						A_off += 4;
						B_off += 4;
					}
				}
			}
#ifdef WIN32
			*R_src =	 v.m128_f32[0] + v.m128_f32[1] + v.m128_f32[2] + v.m128_f32[3];
#else
			float buf[4] __attribute__ ((aligned (16)));
			_mm_store_ps(buf, v);
			_mm_empty();
			*R_src = buf[0]+buf[1]+buf[2]+buf[3];			
#endif
		}
	}
}
Example #10
0
string OCR::getText(Mat src)
{
	if (!src.data)
	{
		cerr << "getText: No image data!" << endl;
		return string("");
	}

	// tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
	// char *configs[] = {"myconfig"};
	// int configs_size = 1;
	// if (!api -> SetVariable("use_definite_ambigs_for_classifier", "1"))
	// {
	// 	cerr << "Unable to set use_definite_ambigs_for_adaption" <<endl;
	// 	exit(-1);
	// }
	// if (!api -> SetVariable("use_ambigs_for_adaption", "1"))
	// {
	// 	cerr << "Unable to set use_ambigs_for_adaption" <<endl;
	// 	exit(-1);
	// }

	// if (api -> Init(NULL, "eng2+fra2+deu2+ita2", tesseract::OEM_DEFAULT, configs, configs_size, NULL, NULL, false))
	// {
	// 	fprintf(stderr, "Could not initialize tesseract.\n");
	// 	exit(-1);
	// }
	



	Mat dst;
	preprocess(src, dst);

	api -> SetImage((uchar*)dst.data, dst.size().width, dst.size().height, 
		dst.channels(), dst.step1());
	
	//Get OCR result
	char *outText = api -> GetUTF8Text();
	string text = outText;

	// api -> End();
	delete [] outText;
	//pixDestroy(&image);
	return text;
}
Example #11
0
string LabelOCR::runPrediction2(const Mat &labelImage, int i){

    string t1;
    if (labelImage.empty())
        return (t1);

    Mat textImage;
    Mat drawImage = labelImage.clone();

    double labelROI_x = labelImage.cols*0.15; // initial point x
    double labelROI_y = labelImage.rows*0.20; // initial point y
    double labelROI_w = labelImage.cols*0.5;  // width
    double labelROI_h = labelImage.rows*0.15; // heigth

    Rect labelROI(labelROI_x, labelROI_y, labelROI_w, labelROI_h);

    Mat midImage;
    preProcess(drawImage, textImage);


    tess.TesseractRect( textImage.data, 1, textImage.step1(), labelROI.x, labelROI.y, labelROI.width, labelROI.height);
    // Get the text
    char* text1 = tess.GetUTF8Text();
    t1 = string(text1);
    if (t1.size() > 2)
        t1.resize(t1.size() - 2);

    cout << "label_" << i << ": " << t1 << endl;

    if (showImages){
        putText(drawImage, t1, Point(labelROI.x+7, labelROI.y-5), FONT_HERSHEY_PLAIN, 1.5, Scalar(0, 0, 255), 2, 8); // CV_FONT_HERSHEY_SIMPLEX
        rectangle(drawImage, labelROI, Scalar(0, 0, 255), 2, 8, 0);
        //
        stringstream ss; ss << i;
        string str = ss.str();

        //imshow("label_"+str, labelImage);
        imshow("textImage_2_"+str, textImage);
        imshow("letters_2_"+str, drawImage);
    }

    return (t1);
}
Example #12
0
void	fconv_1( const Mat &A, const Mat &F, Mat &R )
{
	int		RowA = A.rows, ColA = A.cols, NumFeatures = A.channels();
	int		RowF = F.rows, ColF = F.cols, ChnF = F.channels();
	if( NumFeatures!=ChnF )
		throw runtime_error("");

	int    RowR = RowA - RowF + 1, ColR = ColA - ColF + 1;

	float *Rpt = (float*)R.data;
	int Rstep = R.step1();

	for( int r=0; r!=RowR; r++ ){
		float *pt = Rpt + r*Rstep;
		for( int c=0; c!=ColR; c++ ){
			Mat	Asub = A( Rect(c,r,ColF,RowF) );
			*(pt++) = (float)( F.dot( Asub ) );
		}
	}
}
Example #13
0
string LabelOCR::runPrediction1(const Mat &labelImage, int i){
    string t1;
    if (labelImage.empty())
        return (t1);

    Mat textImage;
    Mat drawImage = labelImage.clone();
	
    Mat midImage;
    preProcess(drawImage, textImage);

	double left_slice = 0.17;
	double labelROI_x = textImage.size().width * left_slice; // initial point x
	double labelROI_y = 0; //textImage.rows*0.76; // initial point y
	double labelROI_w = textImage.size().width * (1 - left_slice);  // width
	double labelROI_h = textImage.size().height; // heigth

	Rect labelROI(labelROI_x, labelROI_y, labelROI_w, labelROI_h);

    tess.TesseractRect( textImage.data, 1, textImage.step1(), labelROI.x, labelROI.y, labelROI.width, labelROI.height);

    // Get the text
    char* text1 = tess.GetUTF8Text();
    t1 = string(text1);
    if (t1.size() > 2)
        t1.resize(t1.size() - 2);
	
    if (showImages){
		ImageProcess tem;
		IplImage* temI = new IplImage(textImage);

		IplImage* temI2 = NULL;
		CvRect* labelROI2 = new CvRect;
		labelROI2->x = labelROI_x; labelROI2->y = labelROI_y; labelROI2->width = labelROI_w; labelROI2->height = labelROI_h;
		tem.CutImage(temI, labelROI2, temI2);
		tem.ShowImage(temI2);

    }

    return (t1);
}
int main()
{



	Mat findImage = imread("sudo.jpg", IMREAD_GRAYSCALE); //이 이미지

	int tempsudo[81] = { 0 };
	int sudoku[9][9] = { 0 };




	Mat cloneImage = findImage.clone();
	threshold(findImage, findImage, 200, 255, THRESH_BINARY);
	//adaptiveThreshold(findImage, findImage, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 21, 2);
	imshow("findImage", findImage);
	waitKey();
	Mat srcImage2 = findImage.clone();

	Mat dstImage(srcImage2.size(), CV_8UC3);

	vector<vector<Point> > beforeContoursforRectangle;//스도쿠 이미지만 빼기위한 경계선
	vector<vector<Point> > AfterContoursforSmallRectangle; //스도쿠에서 작은 네모만 빼기위한경계선
	vector<vector<Point> > configurBackground;

	vector<Vec4i> hierarchy; //외곽선용
	vector<Vec4i> hierarchy2; //81개칸용
	vector<Vec4i> hierarchy3; //배경 검사용


	vector<vector<Point>> cutSize;//외곽선용
	vector<vector<Point>> cutSize2;//81개칸용
	vector<vector<Point>> cutSize3; //배경 검사용



	int mode = RETR_TREE;
	int method = CHAIN_APPROX_NONE;
	Rect r;
	findContours(findImage, beforeContoursforRectangle, hierarchy, mode, method); //윤곽석 검출


	cout << "beforeContoursforRectangle.size()=" << beforeContoursforRectangle.size() << endl; //윤곽선네모 개수

	cout << findImage.size() << endl; //이미지 크기

	int countMax = beforeContoursforRectangle[0].size(); //최대크기를 찾기위한 변수선언

	for (int k = 0; k < beforeContoursforRectangle.size(); k++)
	{
		if (beforeContoursforRectangle[k].size()>countMax)
			countMax = beforeContoursforRectangle[k].size();
	}

	for (int k = 0; k < beforeContoursforRectangle.size(); k++)
	{
		if (beforeContoursforRectangle[k].size()>(countMax*0.6))//스토쿠 판만 빼오기 
		{
			cutSize.push_back(beforeContoursforRectangle[k]);
		}
	}
	/*
	//테스트용
	Mat testtImage;
	for (int k = 0; k < cutSize.size(); k++)
	{
	//
	cvtColor(findImage, testtImage, COLOR_GRAY2BGR);
	r = boundingRect(cutSize[k]);//영역 사각형으로 감쌈
	Rect ROI2(r.x, r.y, r.width, r.height);
	drawContours(testtImage, cutSize, k, Scalar(255, 0, 0), 4); //경계선 그림
	cout << r.size() << endl;

	rectangle(testtImage, ROI2, Scalar(128, 255, 255), 2);//네모로 크림




	circle(testtImage, cutSize[k][0], 5, Scalar(123, 123, 123), -1);
	imshow("testtImage", testtImage);
	waitKey();
	}
	*/



	vector<vector<Point>> cuttingArea;
	int pushArea = -1;
	int smaller = cutSize[0].size();

	for (int k = 1; k < cutSize.size(); k++)
	{
		if (cutSize[k].size() < smaller)
		{
			smaller = cutSize[k].size(); //제일 작은거 가져옴 sort(cutsize.begin(),cutsize.end())가안되서 이방법 씀
			pushArea = k;
		}
	}
	cuttingArea.push_back(cutSize[pushArea]);


	r = boundingRect(cuttingArea[0]);
	Rect ROI(r.x, r.y, r.width, r.height); //자를곳을 골라서 영역 표시 

	cout << "bigSize.size()=" << cutSize.size() << endl;




	int eraseSpot = -1;
	int again = 0;



	int mode2 = RETR_LIST;
	int mode3 = RETR_LIST;
	int method2 = CHAIN_APPROX_NONE;
	int method3 = CHAIN_APPROX_NONE;

	Mat roi = cloneImage(ROI); //해당 영역만 가지고옴
	Mat newImage = repeat(roi, 1, 1);
	Mat contourImage = newImage.clone(); //배경에 음영있는것들 검출
	for (int a = 0; a < contourImage.rows; a++)
	{
		for (int b = 0; b < contourImage.cols; b++)
		{
			float te = contourImage.at<uchar>(a, b);
			if (te >= 160 && te < 190)
				contourImage.at<uchar>(a, b) = 250;
		}
	}

	threshold(contourImage, contourImage, 230, 255, THRESH_BINARY);


	imshow("contourImage", contourImage);
	waitKey();
	vector<int> configureRectSizeStorage; //빈칸과 숫자칸 저장
	vector<int> configureRect; //빈칸숫자칸의 최대 최소값을 알기위해 만듬
	vector<Rect> countRect;
	findContours(contourImage, configurBackground, hierarchy3, mode3, method3);

	for (int k = 0; k < configurBackground.size(); k++)
	{
		cutSize3.push_back(configurBackground[k]); //그 경계선위치들을 넣음
	}

	Mat configureBackgroundImage(contourImage.size(), CV_8UC1);
	for (int k = 0; k < cutSize3.size(); k++)
	{
		//
		cvtColor(contourImage, configureBackgroundImage, COLOR_GRAY2BGR);
		r = boundingRect(cutSize3[k]);//영역 사각형으로 감쌈
		Rect ROI2(r.x, r.y, r.width, r.height);
		drawContours(configureBackgroundImage, cutSize3, k, Scalar(255, 0, 0), 4); //경계선 그림
		//cout << r.size() << endl;

		rectangle(configureBackgroundImage, ROI2, Scalar(128, 255, 255), 2);//네모로 크림

		if ((r.width*r.height)>(configureBackgroundImage.rows*configureBackgroundImage.cols) - 20000)
		{		//최대영역은 받지 않음
			//imshow("resultImage", resultImage);
			//waitKey();
			goto here234;

		}
		configureRectSizeStorage.push_back(r.width*r.height); //sorting하기 위해 정리
	here234:{}

		circle(configureBackgroundImage, cutSize3[k][0], 5, Scalar(123, 123, 123), -1);
		//imshow("resultImage", configureBackgroundImage);
		//waitKey();
	}


	sort(configureRectSizeStorage.begin(), configureRectSizeStorage.end());

	int tSpot = -1;
	int tagain = 0;


	for (int k = 0; k < configureRectSizeStorage.size(); k++)
	{
		if (k == configureRectSizeStorage.size() - 1)
			break;

		if ((configureRectSizeStorage[k + 1] - configureRectSizeStorage[k]) >500)
		{
			tSpot = k; //500이 차이나면 따로 넣을곳 정리 
			break;
		}
	}

	for (int k = tSpot + 1; k < configureRectSizeStorage.size(); k++)
	{
		if (tSpot == -1)
			configureRect.push_back(configureRectSizeStorage[tagain++]); //그냥 집어 넣음
		else
			configureRect.push_back(configureRectSizeStorage[k]); //81개 네모 영역만 집어넣음
	}

	int minRectSize2 = configureRect.front(); //최소 네모 사이즈
	int maxRectSize2 = configureRect[configureRect.size() - 1]; //최대 네모 사이즈
	Mat lastConfigure;
	for (int k = 0; k < cutSize3.size(); k++)
	{

		cvtColor(contourImage, lastConfigure, COLOR_GRAY2BGR);
		//imshow("testImage", testImage);
		r = boundingRect(cutSize3[k]);
		Rect ROI2(r.x, r.y, r.width, r.height);
		//cout << r.size() << endl;

		rectangle(lastConfigure, ROI2, Scalar(128, 255, 255), 2);//그림

		if ((minRectSize2 <= (r.width*r.height)) && ((r.width*r.height) <= maxRectSize2))
			countRect.push_back(ROI2); //해당 영역만 비교 하기 위해 넣어줌
		//imshow("lastConfigure", lastConfigure);
		//waitKey();
	}





	vector<int>params; //압축양식사용

	params.push_back(IMWRITE_JPEG_QUALITY);
	params.push_back(9);

	imwrite("sudoOnly.jpg", newImage, params);
	Mat sudokuImage = imread("sudoOnly.jpg", IMREAD_GRAYSCALE);
	Mat realImage = imread("sudoOnly.jpg", IMREAD_GRAYSCALE);
	Mat testSudo = sudokuImage.clone(); //나중에 확인할거
	Size size(5, 5);
	Mat rectKernel = getStructuringElement(MORPH_RECT, size);
	Mat elipseKernel = getStructuringElement(MORPH_ELLIPSE, size);
	Mat crossKernel = getStructuringElement(MORPH_CROSS, size);


	if (countRect.size() != 81)
	{
		cout << "안되지롱" << endl;
		waitKey();

		goto jumpThreshold;
	}

	threshold(sudokuImage, sudokuImage, 230, 255, THRESH_BINARY); //영상 이진화 
	imshow("teswtsteswtse", sudokuImage);
	waitKey();
	goto jumpAdaptiveThreshold;
	//morphologyEx(sudokuImage, sudokuImage, MORPH_CLOSE, rectKernel, Point(-1, -1), 1);

jumpThreshold:
	//threshold(sudokuImage, sudokuImage, 200, 255, THRESH_BINARY);
	//threshold(sudokuImage, sudokuImage, 200, 255, THRESH_OTSU+THRESH_BINARY); //영상 이진화 

	adaptiveThreshold(sudokuImage, sudokuImage, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 21, 1);
	//morphologyEx(sudokuImage, sudokuImage, MORPH_GRADIENT, crossKernel, Point(-1, -1), 1);
	erode(sudokuImage, sudokuImage, crossKernel, Point(-1, -1), 1);
	dilate(sudokuImage, sudokuImage, elipseKernel, Point(-1, -1), 1);
jumpAdaptiveThreshold:



	imshow("sudokuImage", sudokuImage);
	waitKey();

	Mat testImage = realImage.clone();//스도쿠 된것만 복사시킴
	Mat resultImage(testImage.size(), CV_8UC3);
	Mat testSudoImage(realImage.size(), CV_8UC3);
	vector<int> rectSizeStorage; //빈칸과 숫자칸 저장
	vector<int> realRect; //빈칸숫자칸의 최대 최소값을 알기위해 만듬
	vector<Rect> sudokuRect; //칸마다 잘라진 영역 저장된곳
	vector<Rect> temp;
	threshold(testImage, testImage, 200, 255, THRESH_OTSU + THRESH_BINARY);
	//waitKey();
	findContours(sudokuImage, AfterContoursforSmallRectangle, hierarchy2, mode2, method2);
	//스도쿠 원형만 자른곳에서 다시 경계선 그림
	for (int k = 0; k < AfterContoursforSmallRectangle.size(); k++)
	{
		cutSize2.push_back(AfterContoursforSmallRectangle[k]); //그 경계선위치들을 넣음
	}



	for (int k = 0; k < cutSize2.size(); k++)
	{
		//
		cvtColor(testImage, resultImage, COLOR_GRAY2BGR);
		r = boundingRect(cutSize2[k]);//영역 사각형으로 감쌈
		Rect ROI2(r.x, r.y, r.width, r.height);
		drawContours(resultImage, cutSize2, k, Scalar(255, 0, 0), 4); //경계선 그림
		//cout << r.size() << endl;

		rectangle(resultImage, ROI2, Scalar(128, 255, 255), 2);//네모로 크림

		if ((r.width*r.height)>(resultImage.rows*resultImage.cols) - 20000)
		{		//최대영역은 받지 않음
			//imshow("resultImage", resultImage);
			//waitKey();
			goto here;

		}
		rectSizeStorage.push_back(r.width*r.height); //sorting하기 위해 정리
	here:{}

		circle(resultImage, cutSize2[k][0], 5, Scalar(123, 123, 123), -1);
		//imshow("resultImage", resultImage);
		//waitKey();
	}


	sort(rectSizeStorage.begin(), rectSizeStorage.end());

	eraseSpot = -1;
	again = 0;


	for (int k = 0; k < rectSizeStorage.size(); k++)
	{
		if (k == rectSizeStorage.size() - 1)
			break;

		if ((rectSizeStorage[k + 1] - rectSizeStorage[k]) >500)
		{
			eraseSpot = k; //500이 차이나면 따로 넣을곳 정리 
		}
	}

	for (int k = eraseSpot + 1; k < rectSizeStorage.size(); k++)
	{
		if (eraseSpot == -1)
			realRect.push_back(rectSizeStorage[again++]); //그냥 집어 넣음
		else
			realRect.push_back(rectSizeStorage[k]); //81개 네모 영역만 집어넣음
	}


	//소팅이 이미 되서 들어가므로 할 필요 없음
	int minRectSize = realRect.front(); //최소 네모 사이즈
	int maxRectSize = realRect[realRect.size() - 1]; //최대 네모 사이즈

	for (int k = 0; k < cutSize2.size(); k++)
	{

		cvtColor(testImage, resultImage, COLOR_GRAY2BGR);
		//imshow("testImage", testImage);
		r = boundingRect(cutSize2[k]);
		Rect ROI2(r.x, r.y, r.width, r.height);
		//cout << r.size() << endl;

		rectangle(resultImage, ROI2, Scalar(128, 255, 255), 2);//그림

		if ((minRectSize <= (r.width*r.height)) && ((r.width*r.height) <= maxRectSize))
			temp.push_back(ROI2); //해당 영역만 비교 하기 위해 넣어줌
		//	imshow("resultImage2", resultImage);
		//waitKey();
	}

	for (int k = temp.size() - 1; k >= 0; k--)
		sudokuRect.push_back(temp[k]); //반대로 시작하므로 처음1칸부터 비교하기위해 역으로 넣음

	temp.clear();



	vector<int> testSortingOk;
	//각 줄이 순서대로 소팅이 안되있으므로 각 줄마다 왼쪽부터 오른쪽으로 되게 바꿈
	for (int i = 0; i < 81; i += 9)
	{
		int ty = sudokuRect[i].y;
		int ti = i;
		testSortingOk.clear();
		for (int j = i; j < ti + 9; j++)
		{
			testSortingOk.push_back(sudokuRect[j].x);
		}
		sort(testSortingOk.begin(), testSortingOk.end());
		int k = 0;
		for (int j = i; j < ti + 9; j++)
		{
			if (testSortingOk[k] == sudokuRect[j].x)
				temp.push_back(sudokuRect[j]);
			else
			{
				for (int t = i; t <= ti + 9; t++)
				{
					if (testSortingOk[k] == sudokuRect[t].x)
					{
						temp.push_back(sudokuRect[t]);
						break;
					}
				}
			}

			k++;
		}

	}

	sudokuRect.clear();
	erode(resultImage, resultImage, crossKernel, Point(-1, -1), 1);
	dilate(resultImage, resultImage, elipseKernel, Point(-1, -1), 1);
	for (int k = 0; k < temp.size(); k++)
		sudokuRect.push_back(temp[k]);
	for (int k = 0; k < sudokuRect.size(); k++)
	{
		rectangle(resultImage, sudokuRect[k], Scalar(128, 255, 255), 2);//그림
		imshow("testSudoImage34", resultImage);
		waitKey();
	}

		const char *path = "/tessdate";
	TessBaseAPI tess; //tesseract 선언

		//TessBaseAPI *api = new TessBaseAPI();

	tess.Init(NULL, "eng", tesseract::OEM_DEFAULT); //한국어로 인식 기본 숫자 되어있음
	/*
		if (api->Init(NULL, "eng"))
		{
			fprintf(stderr, "could not initailze teseract\n");
			exit(1);
		}
		*/

	string tessRecogNum[81][1]; //글자로 인식해오므로 넣을곳 만들어줌
	int sudoTestte[81]; //스도쿠 번호 넣을곳을 만들어줌
	int d = 0;

	for (int i = 0; i<sudokuRect.size(); i++)
	{
		cvtColor(testSudo, testSudoImage, COLOR_GRAY2BGR);
		rectangle(testSudoImage, sudokuRect[i], Scalar(128, 255, 255), 2);//그림

		Mat cutImage = testSudo(sudokuRect[i]);
		//	imshow("cutImage", cutImage);
		Mat tempImage = repeat(cutImage, 1, 1);


		Mat numberImage = tempImage.clone();//스도쿠 된것만 복사시킴
		//imshow("numberImage", numberImage);
		imwrite("numberImage.jpg", numberImage, params);
		Mat resultNImage(tempImage.size(), CV_8UC3);
		waitKey();

		int height = tempImage.size().height;
		int width = tempImage.size().width;

		int continueNum = 0; //0이 계속되는 수 선언
		int testPixel = (height*width); //최대 픽셀 받아옴

		//그 칸이 빈칸일 경우 골라서 0을 넣음 
		/*
		for (int a = 0; a < tempImage.rows; a++)
		{
			for (int b = 0; b < tempImage.cols; b++)
			{
				float te = tempImage.at<uchar>(a, b);
				if (continueNum >= testPixel)
					break;
				if (te >= 190 && te <= 200)
					tempImage.at<uchar>(a, b) = 255;

				if (te > 200)
					continueNum++;
			}
			if (continueNum >= (testPixel - 10))
				break;
		}
		*/
		if (continueNum >= testPixel){
			sudoTestte[d++] = atoi("0");
			tessRecogNum[i][0] = '0';
			continue;
		}

		//imshow("tempImage", tempImage);

		//waitKey();

	tess.SetImage((uchar*)tempImage.data, tempImage.size().width, tempImage.size().height, tempImage.channels(), tempImage.step1()); //이미지의 데이터 넓이 높이와 채널을 받아옴

		//Pix *image = pixRead("numberImage.jpg");
		//api->SetImage(image);
//
		tess.Recognize(0); //인식 시킴
		const char * out = tess.GetUTF8Text(); //그걸 utf8text로 인식시킴
		//const char * out = api.GetUTF8Text();
		tessRecogNum[i][0] = out;
		if (atoi(out) > 9 || atoi(out) < 0)
			sudoTestte[d++] = 0;
		else
		sudoTestte[d++] = atoi(out);
		//printf("%s", out);

		//cout << endl;

		imshow("testSudoImage", testSudoImage);
		//waitKey();
	}

	cout << endl;
	for (int i = 0; i < 81; i++)
	{
		if (i % 9 == 0 && i>1)
			cout << endl;
		cout << sudoTestte[i] << " ";

	}


	waitKey();


	return 0;
}
void HOGFeatures<T>::features(const Mat& imm, Mat& featm) const {

    // compute the size of the output matrix
    assert(imm.channels() == 1 || imm.channels() == 3);
    bool color  = (imm.channels() == 3);
    const Size imsize = imm.size();
    const Size blocks = Size(round((float)imsize.width / (float)binsize_), round((float)imsize.height / (float)binsize_));
    const Size outsize = Size(max(blocks.width-2, 0), max(blocks.height-2, 0));
    const Size visible = blocks*binsize_;

    Mat histm = Mat::zeros(Size(blocks.width*norient_, blocks.height),  DataType<T>::type);
    Mat normm = Mat::zeros(Size(blocks.width,          blocks.height),  DataType<T>::type);
    featm     = Mat::zeros(Size(outsize.width*flen_,   outsize.height), DataType<T>::type);

    // get the stride of each of the matrices
    const int imstride   = imm.step1();
    const int histstride = histm.step1();
    const int normstride = normm.step1();
    const int featstride = featm.step1();

    // epsilon to avoid division by zero
    const double eps = 0.0001;

    // unit vectors to compute gradient orientation
    const T uu[9] = {1.000, 0.9397, 0.7660, 0.5000, 0.1736, -0.1736, -0.5000, -0.7660, -0.9397};
    const T vv[9] = {0.000, 0.3420, 0.6428, 0.8660, 0.9848,  0.9848,  0.8660,  0.6428,  0.3420};

    // calculate the zero offset
    const IT* im  = imm.ptr<IT>(0);
    T* const hist = histm.ptr<T>(0);
    T* const norm = normm.ptr<T>(0);
    T* const feat = featm.ptr<T>(0);

    // TODO: source image may not be continuous!
    for (int y = 1; y < visible.height-1; ++y) {
        for (int x = 1; x < visible.width-1; ++x) {
            T dx, dy, v;

            // grayscale image
            if (!color) {
                const IT* s = im + min(x, imm.cols-2) + min(y, imm.rows-2)*imstride;
                dy = *(s+imstride) - *(s-imstride);
                dx = *(s+1) - *(s-1);
                v = dx*dx + dy*dy;
            }

            // color image
            // OpenCV uses an interleaved format: BGR-BGR-BGR
            // Matlab uses a planar format:       RRR-GGG-BBB
            if (color) {
                const IT* s = im + 3 * min(x, imm.cols-2) + min(y, imm.rows-2)*imstride;

                // blue image channel
                T dyb = *(s+imstride) - *(s-imstride);
                T dxb = *(s+3) - *(s-3);
                T  vb = dxb*dxb + dyb*dyb;

                // green image channel
                s += 1;
                T dyg = *(s+imstride) - *(s-imstride);
                T dxg = *(s+3) - *(s-3);
                T  vg = dxg*dxg + dyg*dyg;

                // third image channel
                s += 1;
                dy = *(s+imstride) - *(s-imstride);
                dx = *(s+3) - *(s-3);
                v = dx*dx + dy*dy;

                // pick the channel with the strongest gradient
                if (vg > v) {
                    v = vg;
                    dx = dxg;
                    dy = dyg;
                }
                if (vb > v) {
                    v = vb;
                    dx = dxb;
                    dy = dyb;
                }
            }

            // snap to one of 18 orientations
            T best_dot = 0;
            int best_o = 0;
            for (int o = 0; o < norient_/2; ++o) {
                T dot = uu[o]*dx + vv[o]*dy;
                if (dot > best_dot) {
                    best_dot = dot;
                    best_o = o;
                }
                else if (-dot > best_dot) {
                    best_dot = -dot;
                    best_o = o+norient_/2;
                }
            }

            // add to 4 histograms around pixel using linear interpolation
            T yp = ((T)y+0.5)/(T)binsize_ - 0.5;
            T xp = ((T)x+0.5)/(T)binsize_ - 0.5;
            int iyp = (int)floor(yp);
            int ixp = (int)floor(xp);
            T vy0 = yp-iyp;
            T vx0 = xp-ixp;
            T vy1 = 1.0-vy0;
            T vx1 = 1.0-vx0;
            v = sqrt(v);

            if (iyp >= 0 && ixp >= 0) 							*(hist + iyp*histstride + ixp*norient_ + best_o) += vy1*vx1*v;
            if (iyp >= 0 && ixp+1 < blocks.width) 				*(hist + iyp*histstride + (ixp+1)*norient_ + best_o) += vx0*vy1*v;
            if (iyp+1 < blocks.height && ixp >= 0) 				*(hist + (iyp+1)*histstride + ixp*norient_ + best_o) += vy0*vx1*v;
            if (iyp+1 < blocks.height && ixp+1 < blocks.width)	*(hist + (iyp+1)*histstride + (ixp+1)*norient_ + best_o) += vy0*vx0*v;
        }
    }

    // compute the energy in each block by summing over orientations
    for (int y = 0; y < blocks.height; ++y) {
        const T* src = hist + y*histstride;
        T* dst = norm + y*normstride;
        T const * const dst_end = dst + blocks.width;
        while (dst < dst_end) {
            *dst = 0;
            for (int o = 0; o < norient_/2; ++o) {
                *dst += square( *src + *(src+norient_/2) );
                src++;
            }
            dst++;
            src += norient_/2;
        }
    }

    // compute the features
    for (int y = 0; y < outsize.height; ++y) {
        for (int x = 0; x < outsize.width; ++x) {
            T* dst = feat + y*featstride + x*flen_;
            T* p, n1, n2, n3, n4;
            const T* src;

            p  = norm + (y+1)*normstride + (x+1);
            n1 = 1.0f / sqrt(*p + *(p+1) + *(p+normstride) + *(p+normstride+1) + eps);
            p  = norm + y*normstride + (x+1);
            n2 = 1.0f / sqrt(*p + *(p+1) + *(p+normstride) + *(p+normstride+1) + eps);
            p  = norm + (y+1)*normstride + x;
            n3 = 1.0f / sqrt(*p + *(p+1) + *(p+normstride) + *(p+normstride+1) + eps);
            p  = norm + y*normstride + x;
            n4 = 1.0f / sqrt(*p + *(p+1) + *(p+normstride) + *(p+normstride+1) + eps);

            T t1 = 0, t2 = 0, t3 = 0, t4 = 0;

            // contrast-sensitive features
            src = hist + (y+1)*histstride + (x+1)*norient_;
            for (int o = 0; o < norient_; ++o) {
                T val = *src;
                T h1 = min(val * n1, (T)0.2);
                T h2 = min(val * n2, (T)0.2);
                T h3 = min(val * n3, (T)0.2);
                T h4 = min(val * n4, (T)0.2);
                *(dst++) = 0.5 * (h1 + h2 + h3 + h4);
                src++;
                t1 += h1;
                t2 += h2;
                t3 += h3;
                t4 += h4;
            }

            // contrast-insensitive features
            src = hist + (y+1)*histstride + (x+1)*norient_;
            for (int o = 0; o < norient_/2; ++o) {
                T sum = *src + *(src+norient_/2);
                T h1 = min(sum * n1, (T)0.2);
                T h2 = min(sum * n2, (T)0.2);
                T h3 = min(sum * n3, (T)0.2);
                T h4 = min(sum * n4, (T)0.2);
                *(dst++) = 0.5 * (h1 + h2 + h3 + h4);
                src++;
            }

            //texture features
            *(dst++) = 0.2357 * t1;
            *(dst++) = 0.2357 * t2;
            *(dst++) = 0.2357 * t3;
            *(dst++) = 0.2357 * t4;

            // truncation feature
            *dst = 0;
        }
    }
}
Example #16
0
void RecognizeLP::read_image(int width, int height, char *image, Mat& scene_plate, string& lpr,int& count_letters)
{
	cv::Mat Image(height, width, CV_8UC3, image);
	// you may need to define the area of interest, where the test is found
	cout<<"count_letters: "<<count_letters<<endl;
	// initializing Tesseract API
	char *outText;
	double confidence = 0;
	//do{
	tesseract::TessBaseAPI *tess_api = new tesseract::TessBaseAPI();
	if (tess_api->Init(NULL, "eng"))  // eng is a flag of which trained language you use, if you just train your own language, you gave "XYZ" as a falge, you have to use it here
	{
		cout<<"Could not initialize tesseract.\n";
		exit(1);
	}
	//tess_api->SetVariable("tessedit_char_whitelist", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345789");
	//tess_api->SetVariable("tessedit_char_whitelist", "0123456789");
	if(count_letters < 2)
		tess_api->SetVariable("tessedit_char_whitelist", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
	if(count_letters >=2 && count_letters < 4)
		tess_api->SetVariable("tessedit_char_whitelist", /*"ABCDEFGHIJKLMNOPQRSTUVWXYZ"*/"0123456789");
	if(count_letters>=4  && count_letters < 6)
		tess_api->SetVariable("tessedit_char_whitelist", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
	if(count_letters>=6 && count_letters < 10)
		tess_api->SetVariable("tessedit_char_whitelist", /*"ABCDEFGHIJKLMNOPQRSTUVWXYZ"*/"0123456789");
	//tess_api->SetVariable("tessedit_char_whitelist", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
	//	if(count_letters>14)
	//	tess_api->SetVariable("tessedit_char_whitelist", /*"ABCDEFGHIJKLMNOPQRSTUVWXYZ"*/"0123456789");
	//	else
	//	tess_api->SetVariable("tessedit_char_whitelist", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789X");

	tess_api->SetVariable("classify_font_name", "Arial.ttf");
	tess_api->SetVariable("segment_penalty_garbage", "0");
	tess_api->SetVariable("segment_penalty_dict_nonword", "0");
	tess_api->SetVariable("segment_penalty_dict_frequent_word", "0");
	tess_api->SetVariable("segment_penalty_dict_case_ok", "0");
	tess_api->SetVariable("segment_penalty_dict_case_bad", "0");


	if(!tess_api->SetVariable("tessedit_enable_doc_dict", "0"))
	{
		cout << "Unable to enable dictionary" << endl;
	}
	tess_api->SetPageSegMode(tesseract::PSM_SINGLE_WORD);
	tess_api->SetImage((uchar*)scene_plate.data, scene_plate.size().width,scene_plate.size().height,scene_plate.channels(),scene_plate.step1());
	tess_api->Recognize(0);
	//char* out =tess_api->GetUTF8Text();
	string temp = tess_api->GetUTF8Text();

	temp.erase(std::remove(temp.begin(), temp.end(), '\n'), temp.end());
	temp.erase(std::remove(temp.begin(), temp.end(), ' '), temp.end());
	confidence = tess_api->MeanTextConf();
	//cout<<"OCR output:"<< out<< "  with confidence "<<confidence<<endl;
	//lpr << out; 
	//cout<<temp.length()<<endl;

	//	if(temp.length() <= 5){
	//		lpr +=temp;
	//		if( temp.length() == 1 || temp.length() == 2 || temp.length() == 5 || temp.length() == 6 && isalpha(temp[0])){
	//	if(temp.length() == 1)
	lpr.append(temp);
	count_letters +=temp.length();
	//		}
	//		else if( temp.length() == 3 || temp.length() == 4 || temp.length() == 7 || temp.length() == 8 || temp.length() == 9 || temp.length() == 10 && isdigit(temp[0])){
	//		lpr.append(temp);
	//                count_letters +=temp.length();
	//		}
	//		else{
	//		cout<<"Not a valid License Plate"<<endl;	
	//		exit(0);
	//		}
	cout<<count_letters - 1<<"\t|\t"<<lpr<<endl;
	//	}
	//	else{
	//		count_non_letters +=temp.length();
	//	}
	//lpr.append(out);
	//cout<<lpr;

	//}while(confidence < 90);
}
Example #17
0
int detectNumber(Mat img){
 //Mat circ = copyContour(img, circle);

 inRange(img, Scalar(0, 0, 51), Scalar(255, 255, 255), img); //filter black
 tess.SetImage((uchar*)img.data, img.size().width, img.size().height, img.channels(), img.step1());
 //tess.SetRectangle(circle[0]-circle[2], circle[1]-circle[2],2*circle[2],2*circle[2]);
 string out = string (tess.GetUTF8Text());
 out.erase( std::remove_if( out.begin(), out.end(), ::isspace ), out.end() );
 const char* result = out.c_str();
 //printf("%s\n", result);
 switch(atoi(result)){
	case 10: return 5;
	case 20: return 6;
	case 30: return 7;
	case 40: return 8;
	case 50: return 9;
	case 60: return 10;
	case 70: return 11;
	case 80: return 12;
 }
 //rectangle(img, Point(circle[0]-circle[2], circle[1]-circle[2]), Point(circle[0]+circle[2], circle[1]+circle[2]), Scalar (100,255,255),3,8,0);
 // imwrite("./test.png", img);
 return -1;}
Example #18
0
    void run(Mat& image, string& output, vector<Rect>* component_rects=NULL,
             vector<string>* component_texts=NULL, vector<float>* component_confidences=NULL,
             int component_level=0)
    {

        CV_Assert( (image.type() == CV_8UC1) || (image.type() == CV_8UC3) );

#ifdef HAVE_TESSERACT

        if (component_texts != 0)
            component_texts->clear();
        if (component_rects != 0)
            component_rects->clear();
        if (component_confidences != 0)
            component_confidences->clear();

        tess.SetImage((uchar*)image.data, image.size().width, image.size().height, image.channels(), image.step1());
        tess.Recognize(0);
        char *outText;
        outText = tess.GetUTF8Text();
        output = string(outText);
        delete [] outText;

        if ( (component_rects != NULL) || (component_texts != NULL) || (component_confidences != NULL) )
        {
            tesseract::ResultIterator* ri = tess.GetIterator();
            tesseract::PageIteratorLevel level = tesseract::RIL_WORD;
            if (component_level == OCR_LEVEL_TEXTLINE)
                level = tesseract::RIL_TEXTLINE;

            if (ri != 0) {
                do {
                    const char* word = ri->GetUTF8Text(level);
                    if (word == NULL)
                        continue;
                    float conf = ri->Confidence(level);
                    int x1, y1, x2, y2;
                    ri->BoundingBox(level, &x1, &y1, &x2, &y2);

                    if (component_texts != 0)
                        component_texts->push_back(string(word));
                    if (component_rects != 0)
                        component_rects->push_back(Rect(x1,y1,x2-x1,y2-y1));
                    if (component_confidences != 0)
                        component_confidences->push_back(conf);

                    delete[] word;
                } while (ri->Next(level));
            }
            delete ri;
        }

        tess.Clear();

#else

        cout << "OCRTesseract(" << component_level << image.type() <<"): Tesseract not found." << endl;
        output.clear();
        if(component_rects)
            component_rects->clear();
        if(component_texts)
            component_texts->clear();
        if(component_confidences)
            component_confidences->clear();
#endif
    }
int main(int argc, char* argv[]) {

  // initilize tesseract OCR engine
  tesseract::TessBaseAPI *myOCR =
    new tesseract::TessBaseAPI();

  printf("Tesseract-ocr version: %s\n",
         myOCR->Version());
  // printf("Leptonica version: %s\n",
  //        getLeptonicaVersion());

  if (myOCR->Init(NULL, "eng")) {
    fprintf(stderr, "Could not initialize tesseract.\n");
    exit(1);
  }

  tesseract::PageSegMode pagesegmode = static_cast<tesseract::PageSegMode>(7); // treat the image as a single text line
  myOCR->SetPageSegMode(pagesegmode);

  // read iamge
  namedWindow("tesseract-opencv", 0);
  Mat image = imread("sample.png", 0);

  // set region of interest (ROI), i.e. regions that contain text
  Rect text1ROI(80, 50, 800, 110);
  Rect text2ROI(190, 200, 550, 50);

  // recognize text
  myOCR->TesseractRect( image.data, 1, image.step1(), text1ROI.x, text1ROI.y, text1ROI.width, text1ROI.height);
  const char *text1 = myOCR->GetUTF8Text();

  myOCR->TesseractRect( image.data, 1, image.step1(), text2ROI.x, text2ROI.y, text2ROI.width, text2ROI.height);
  const char *text2 = myOCR->GetUTF8Text();

  // remove "newline"
  string t1(text1);
  t1.erase(std::remove(t1.begin(), t1.end(), '\n'), t1.end());

  string t2(text2);
  t2.erase(std::remove(t2.begin(), t2.end(), '\n'), t2.end());

  // print found text
  printf("found text1: \n");
  printf(t1.c_str());
  printf("\n");

  printf("found text2: \n");
  printf(t2.c_str());
  printf("\n");

  // draw text on original image
  Mat scratch = imread("sample.png");

  int fontFace = FONT_HERSHEY_PLAIN;
  double fontScale = 2;
  int thickness = 2;
  putText(scratch, t1, Point(text1ROI.x, text1ROI.y), fontFace, fontScale, Scalar(0, 255, 0), thickness, 8);
  putText(scratch, t2, Point(text2ROI.x, text2ROI.y), fontFace, fontScale, Scalar(0, 255, 0), thickness, 8);

  rectangle(scratch, text1ROI, Scalar(0, 0, 255), 2, 8, 0);
  rectangle(scratch, text2ROI, Scalar(0, 0, 255), 2, 8, 0);

  imshow("tesseract-opencv", scratch);
  waitKey(0);

  delete [] text1;
  delete [] text2;

  // destroy tesseract OCR engine
  myOCR->Clear();
  myOCR->End();

  return 0;
}
Example #20
0
//----------------------------------------------------------------------------------
void OCRit(Mat inputimg, vector<vector<Point>>points, char data[][60], Mat &outputimg, char lang[]){
	TessBaseAPI tess;
	
	tess.Init(NULL, lang, OEM_DEFAULT);
	cout << "\n\n";
	for (unsigned int c = 0; c < points.size(); c++){
		Mat imag = inputimg(Rect(points[c][0], points[c][1]));
		Mat img;
		cvtColor(imag, img, COLOR_BGR2GRAY);//use img to do ocr now

		tess.SetImage((uchar*)img.data, img.size().width, img.size().height, img.channels(), img.step1());
		char* out = tess.GetUTF8Text();
		cout << c + 1 << " -- " << out << "\n";
		strcpy(data[c],out);
		//removed to prevent alteration of original pan
		//rectangle(outputimg, points[c][0], points[c][1],1,4,0);
	}



}
Example #21
0
// 因为featpyramid()中对各个pyra.feat[i]进行0/1扩展耗费了大量时间,为了减小这个开支,这里直接对计算的feature扩展
Mat		PM_type::features14_2( const Mat &image, const int sbin, const int pad[2] )
{
	const int	dims[3] = { image.rows, image.cols, image.channels() };
	const int	row_step = image.cols * image.channels();
	const float * const imgpt = image.ptr<float>(0,0);
	if( image.type()!=CV_32FC3 )
		throw runtime_error("Invalid input");

	// memory for caching orientation histograms & their norms
	const int	blocks[2] = {  (int)(0.5f+(float)dims[0]/(float)sbin), (int)(0.5f+(float)dims[1]/(float)sbin) };
	const int	block_sz = blocks[0] * blocks[1];
	const int	visible[2] = { blocks[0]*sbin, blocks[1]*sbin };

	Mat		histmat[9];
	float		*hist[9];	
	int			hist_step[9];
	Mat		hist_tmp = Mat::zeros( blocks[0], blocks[1]*9, CV_32FC1 );
	for( int i=0; i<9; i++ ){
		//histmat[i] = Mat::zeros( blocks[0], blocks[1], CV_32FC1 );
		histmat[i] = hist_tmp( Rect(i*blocks[1],0,blocks[1],blocks[0]) );
		hist[i] = histmat[i].ptr<float>(0,0);
		hist_step[i] = histmat[i].step1();
	}

	// 1. Calculate the original HOG
	for (int yy = 1; yy < visible[0]-1; yy++) { // each row
		int		y = MIN(yy,dims[0]-2);
		const float	*imgpt1 = imgpt + y*row_step;
		for (int xx = 1; xx < visible[1]-1; xx++) { // each col
			int		x = MIN(xx,dims[1]-2);

			// b-g-r color at (y,x) is { *s, *(s+1), *(s+2) }
			const float	*s = imgpt1 + x*dims[2];
			float Right[3] = { *(s+3), *(s+4), *(s+5) }; 
			float Left[3] = { *(s-3), *(s-2), *(s-1) };
			float Up[3] = { *(s-row_step), *(s+1-row_step), *(s+2-row_step) };
			float Down[3] = { *(s+row_step), *(s+1+row_step), *(s+2+row_step) };

			// gradients and amplitude of orientations of each channel
			float	dxs, dys, vs;
			float	dx, dy, v=-1;
			for( int i=0; i!=3; i++ ){
				dxs = Right[i] - Left[i];
				dys = Down[i] - Up[i];
				vs = dxs*dxs + dys*dys;
				if( vs>=v ){
					v = vs;
					dx = dxs;
					dy = dys;
				}
			}

			//int best_o = yuSnap9_V1( dx, dy );
			//int best_o = yuSnap9( dx, dy );
			int best_o = 0;
			{
				// snap to 1 of the 9 orientations
				float a[4] = { uu[1]*dx, uu[2]*dx, uu[3]*dx, uu[4]*dx };
				float b[4] = { vv[1]*dy, vv[2]*dy, vv[3]*dy, vv[4]*dy };
				float dots[9] = { dx, a[0]+b[0], a[1]+b[1], a[2]+b[2], a[3]+b[3], b[3]-a[3], b[2]-a[2], b[1]-a[1], b[0]-a[0] }; // uu[i]*dx+vv[i]*dy
				float best_dot = 0;
				for( int i=0; i<9; i++ ){
					if( dots[i]<0 )
						dots[i] = -dots[i];
					if( dots[i]>best_dot ){
						best_dot = dots[i];
						best_o = i;
					}
				}
			}

			// add to 4 histograms around pixel using linear interpolation
			float xp = (xx+0.5f)/(float)sbin - 0.5f;
			float yp = (yy+0.5f)/(float)sbin - 0.5f;
			//int ixp = (int)floorf(xp),  iyp = (int)floorf(yp);
			int ixp = (int)xp, iyp = (int)yp;
			if( xp<0 && xp!=ixp )
				ixp--;
			if( yp<0 && yp!=iyp )
				iyp--;
			int ixp_p = ixp + 1, iyp_p = iyp + 1;
			float vx0 = xp-ixp, vy0 = yp-iyp;
			float vx1 = 1.f-vx0, vy1 = 1.f-vy0;
			v = sqrtf(v);

			if( ixp<0 ){
				ixp = 0;
				vx1 = 0;
			}
			if( ixp_p>=blocks[1] ){
				ixp_p = blocks[1] - 1;
				vx0 = 0;
			}
			if( iyp<0 ){
				iyp = 0;
				vy1 = 0;
			}
			if( iyp_p>=blocks[0] ){
				iyp_p = blocks[0] - 1;
				vy0 = 0;
			}

			float	*hist_pt = hist[best_o] + iyp*hist_step[best_o] + ixp;
			ixp_p = ixp_p - ixp;
			iyp_p = iyp_p - iyp;
			*(hist_pt) += vx1*vy1*v;
			*(hist_pt + ixp_p) += vx0*vy1*v;
			*(hist_pt + iyp_p*hist_step[best_o]) += vx1*vy0*v;
			*(hist_pt + iyp_p*hist_step[best_o] + ixp_p) += vx0*vy0*v;
		}
	}

	// 2. Compute energy in each block by summing over orientations
	Mat		normmat = Mat::zeros( blocks[0], blocks[1], CV_32FC1 );
	float * const norm = normmat.ptr<float>(0,0);
	const int	norm_step = normmat.step1();
	for( int i=0; i<9; i++ )
		accumulateSquare( histmat[i], normmat );

	// normalization coefficients
	Mat	Normmss(blocks[0]-1,blocks[1]-1,CV_32FC1);
	float * const Norms = Normmss.ptr<float>(0,0);
	const int	norms_step = Normmss.step1();
	for( int i=0; i<Normmss.rows; i++ ){
		float	*src = norm + i*norm_step;
		float	*dst = Norms + i*norms_step;
		for( int j=0; j<Normmss.cols; j++ ){
			float	tmp = *src + *(src+1) + *(src+norm_step) + *(src+norm_step+1) + eps;
			//*(dst++) = 1.f / sqrtf(tmp);
			*(dst++) = tmp;
			src++;
		}
	}
	cv::sqrt( Normmss, Normmss );
	Normmss = 1.f / Normmss;

	// 3. Reduced HOG features.
	int out[3];
	out[0] = MAX(blocks[0]-2, 0);
	out[1] = MAX(blocks[1]-2, 0);
	out[2] = 9+4+1; // 14 dimensional features
	out[2] += 2; // 16 dimensional features finally
	Mat	feat_mat( out[0]+2*pad[0], out[1]+2*pad[1], CV_32FC(out[2]) );
	Vec<float,16>	init_val;
	init_val = 0;
	init_val[13] = 1;
	feat_mat.setTo( init_val );
	float * const feat_data = feat_mat.ptr<float>(pad[0],pad[1]);
	const int feat_step = feat_mat.step1();

	for( int y=0; y<out[0]; y++ ){
		float	*dst = feat_data + y*feat_step;
		float	*Normpt = Norms + y*norms_step;
		for( int x=0; x<out[1]; x++ ){
			// 			
			float	n4 = *Normpt;
			float	n2 = *(Normpt+1);
			float	n3 = *(Normpt+norms_step);
			float	n1 = *(Normpt+norms_step+1);
			Normpt++;

			float	t1 = 0, t2 = 0, t3 = 0, t4 = 0;

			// 9 contrast-insensitive features
			for( int i=0; i<9; i++ ){
				float	src = *( hist[i]+(y+1)*hist_step[i]+x+1 );
				//float	src = histmat_insens[i].at<float>(y+1,x+1);
				float h1 = MIN(src * n1, 0.2f);
				float h2 = MIN(src * n2, 0.2f);
				float h3 = MIN(src * n3, 0.2f);
				float h4 = MIN(src * n4, 0.2f);
				*(dst++) = 0.5f * (h1 + h2 + h3 + h4);
				t1 += h1;
				t2 += h2;
				t3 += h3;
				t4 += h4;
			}

			// 4 texture features
			*(dst++) = 0.3333f * t1;
			*(dst++) = 0.3333f * t2;
			*(dst++) = 0.3333f * t3;
			*(dst++) = 0.3333f * t4;

			// 1 truncation feature	 and 2 supplementary features
			//dst += 3;
			*(dst++) = 0;
			*(dst++) = 0;
			*(dst++) = 0;

		}
	}

	return	feat_mat;
}