opencv利用案例,使用形态学的办法计算如下文字的行角度,以利于后续处理中将文字角度矫正。
在以前的方法中使用houg变化的方法求取直线群,然后用计算直线平均角的办法计算整体角度。
这里使用形态学办法;
void compute_skew(const char* filename)
{
cv::Mat img = cv::imread(filename, 0);
cv::threshold(img, img, 225,255,cv::THRESH_BINARY);
cv::bitwise_not(img,img);
//cv::imshow("Result", img);
//cv::waitKey(0);
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 3));
cv::erode(img, img, element);
std::vector<cv::Point> points;
cv::Mat_<uchar>::iterator it = img.begin<uchar>();
cv::Mat_<uchar>::iterator end = img.end<uchar>();
for(; it != end; it++)
{
if(*it)
points.push_back(it.pos());
}
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
double angle = box.angle;
if(angle < -45.)
angle += 90.;
cv::Point2f vertices[4];
box.points(vertices);
for(int i = 0; i< 4; ++i)
cv::line(img, vertices[i], vertices[(i+1)%4],cv::Scalar(255,0,0),
1, CV_AA);
std::cout << "File" << filename << ": " << angle << std::endl;
cv::imshow("Result", img);
cv::waitKey(0);
}
重要点分析:
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 3))
getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1))
Returns a structuring element of the specified size and shape for morphological operations;
返回一个构造元素,用于erode();
std::vector points;
cv::Mat_::iterator it = img.begin();
cv::Mat_::iterator end = img.end();
定义遍历图像的迭代器,因为图像是单通道图,故使用;
for(; it != end; it++)
{
if(*it)
points.push_back(it.pos());
}
将腐蚀后图像中有点的位置储存到vector中;
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
找出包含所有点位置的最小矩形框。 这里的点有事mat格式中的点;
for(int i = 0; i< 4; ++i)
cv::line(img, vertices[i], vertices[(i+1)%4],cv::Scalar(255,0,0),
1, CV_AA);
最小矩形框绘制
结果如图