图像文字区域提取

#include "stdafx.h"
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string.h>
 
using namespace cv;
using namespace std;
const string IMAGEPATH = "D:/Program Files/projects/TriggerCount_MutiThread/相机00312779/20171225163059.jpg";//图像路径


Mat preprocess(Mat gray)
{
	//1.Sobel算子,x方向求梯度
//	Mat sobel;
//	Sobel(gray, sobel, CV_8U, 1, 0, 3);

	//2.二值化
//	Mat binary;
//	threshold(sobel, binary, 0, 255, THRESH_OTSU + THRESH_BINARY);
	Mat middle;
	Mat erzhi(gray.size(), CV_8U, Scalar(0));  //0是黑,255是白
	blur(gray, middle, Size(5, 5));             //降噪处理
	threshold(middle, erzhi, 60, 255, THRESH_BINARY_INV);    //二值化取反
	//3.膨胀和腐蚀操作核设定
	Mat element1 = getStructuringElement(MORPH_RECT, Size(20, 30));
	//控制高度设置可以控制上下行的膨胀程度,例如3比4的区分能力更强,但也会造成漏检
	Mat element2 = getStructuringElement(MORPH_RECT, Size(40, 40));

	//4.膨胀一次,让轮廓突出
	Mat dilate1;
	dilate(erzhi, dilate1, element2);
	
	//5.腐蚀一次,去掉细节,表格线等。这里去掉的是竖直的线
	Mat erode1;
	erode(dilate1, erode1, element1);

	//6.再次膨胀,让轮廓明显一些
	Mat dilate2;
	dilate(erode1, dilate2, element2);

	//7.存储中间图片
	return dilate2;
}


vector<RotatedRect> findTextRegion(Mat img)
{
	vector<RotatedRect> rects;
	//1.查找轮廓
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(img, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE, Point(0, 0));

	//2.筛选那些面积小的
	for (int i = 0; i < contours.size(); i++)
	{
		//计算当前轮廓的面积
		double area = contourArea(contours[i]);

		//面积小于1000的全部筛选掉
		if (area < 30000)
			continue;

		//轮廓近似,作用较小,approxPolyDP函数有待研究
		double epsilon = 0.001*arcLength(contours[i], true);
		Mat approx;
		approxPolyDP(contours[i], approx, epsilon, true);

		//找到最小矩形,该矩形可能有方向
		RotatedRect rect = minAreaRect(contours[i]);

		//计算高和宽
		int m_width = rect.boundingRect().width;
		int m_height = rect.boundingRect().height;

		//筛选那些太细的矩形,留下扁的
		if (m_height > m_width * 1.2)
			continue;

		//符合条件的rect添加到rects集合中
		rects.push_back(rect); 
	}
	return rects;
}

void detect(Mat img)
{
	//1.转化成灰度图
	Mat gray;
	cvtColor(img, gray, CV_BGR2GRAY);
	imshow("gray", gray);
	//2.形态学变换的预处理,得到可以查找矩形的轮廓
	Mat dilation = preprocess(gray);

	//3.查找和筛选文字区域
	vector<RotatedRect> rects = findTextRegion(dilation);

	
	//4.用绿线画出这些找到的轮廓
	for each (RotatedRect rect in rects)
	{
		Point2f P[4];
		rect.points(P);
		for (int j = 0; j <= 3; j++)
		{
//			line(gray, P[j], P[(j + 1) % 4], Scalar(0, 255, 0), 2);
			
		}
		Mat mask = Mat::zeros(img.size(), CV_8UC1);

		Rect rect;
		rect.x = P[2].x;
		rect.y = P[2].y;
		rect.width = P[3].x-P[2].x;
		rect.height = P[1].y - P[2].y;
		//设置矩形掩模
		mask(rect).setTo(255);

		Mat img2=img(rect);
//		img.copyTo(img2, mask);
		imshow("img2", img2);
		imwrite("数字区域.jpg", img2);
	}

	//5.显示带轮廓的图像
//	imshow("img", img);
	
	
	
	waitKey(0);
}
 
int  main()
{
	Mat textImageSrc = imread(IMAGEPATH);
	detect(textImageSrc);

	return 0;
	}  

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值