这里的原图为: 分块要求为:
原理为:
从左到右,从上到下,进行填充,在此基础上以整张图片的中间位置来判断,每块相对于中线所处的位置,比如1块,则表示相交,2表示在中线的左边,3表示中线的右边,当每块位置出来后,逻辑顺序如下:symbol表示出现1这种情况下,它上面有没有没有push到指定目标容器的块
当然这是在图片大致为两栏的情况下。
代码如下:
// a7.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <opencv245.h>
#include <vector>
#include <algorithm>
using namespace std;
using namespace cv;
void paintRect(Mat &src, Rect &rect)
{
float LTopX = static_cast<float>(rect.x);
float LTopY = static_cast<float>(rect.y);
float RBtmX = static_cast<float>(rect.x + rect.width - 1);
float RBtmY = static_cast<float>(rect.y + rect.height - 1);
Point LTopPonit(LTopX, LTopY);
Point RBtmPoint(RBtmX, RBtmY);
rectangle( src, LTopPonit, RBtmPoint, Scalar(0, 0, 255), 1, 8);
}
void imgProc(Mat &image, Vector<Rect> &VecRect)
{
for (auto it = VecRect.begin(); it != VecRect.end(); it++)
{
paintRect(image, *it);
}
}
//定义矩形的rect类来表示排序的规则,这里的规则是,由y值从小变大
bool sortbyY( Rect rect1, Rect rect2)
{
return rect1.y < rect2.y;
}
//块整合
Vector<Rect> mergeRect(int barThreshold, Vector<Rect> VecRect)
{
bool symbol = false; //表示其上没块
Vector<Rect> VecRectRight;
Vector<Rect> VecRectThink;
/*VecRectThink.resize(VecRect.size());*/
for (auto it = VecRect.begin(); it != VecRect.end(); ++it)
{
if ( ( (*it).x + (*it).width ) < barThreshold) //说明此块在中线的左边
{
//此块上面没块
VecRectThink.push_back(*it);
/*for (auto it = VecRectThink.begin(); it != VecRectThink.end(); ++it)
{
cout<<*it<<endl;
}*/
symbol = true;
}
else if ( (*it).x > barThreshold ) //说明此块在中线的右边
{
VecRectRight.push_back(*it);
symbol = true;
}
else //说明此块在中间
{
if (!symbol) //表示在碰到bar时,其上面没有块
{
VecRectThink.push_back(*it);
symbol = false;
}
else
{
for (auto itR = VecRectRight.begin(); itR != VecRectRight.end(); itR++)
{
VecRectThink.push_back(*itR);
}
VecRectRight.clear();
VecRectThink.push_back(*it);
symbol = false;
}
}
}
if (VecRectRight.size())
{
for (auto itR = VecRectRight.begin(); itR != VecRectRight.end(); itR++)
VecRectThink.push_back(*itR);
}
return VecRectThink;
}
int _tmain(int argc, _TCHAR* argv[])
{
Mat src, dst, element;
Vector<Rect> VecRect;
Vector<Rect> VecRectLast;
int count = 1;
Rect rectS;
Rect rectL;
/*RNG rng = theRNG();*/
src = imread("C:\\Users\\sony\\Desktop\\测试下.png", 0);
imshow("src",src);
waitKey(0);
resize(src, dst, Size( 400, int(400.0*src.cols/src.rows) ) );
threshold(src, dst, 160, 255, THRESH_BINARY);
/*element = getStructuringElement(MORPH_RECT, Size(5,5),Point(-1, -1));
morphologyEx(dst, dst, MORPH_CLOSE, element, Point(-1,-1));
morphologyEx(dst, dst, MORPH_CLOSE, element, Point(-1,-1));
dilate(dst,dst,Mat(),Point(-1,-1),1);*/
erode(dst,dst,Mat(),Point(-1,-1),1);
/*imshow("1",dst);
waitKey(0);*/
/*cvtColor(dst,dst,CV_GRAY2BGR);*/
cvtColor(src,src,CV_GRAY2BGR);
for (int j = 0; j < dst.rows; j++)
{
for (int i = 0; i < dst.cols; i++)
{
if ( dst.at<uchar>(j, i) == 0 )
{
floodFill(dst, Point(i, j), count++, &rectS);
rectL.x = rectS.x * src.cols * 1.0 / 400 - 2;
rectL.y = rectS.y * src.cols * 1.0 / 400 - 2;
rectL.width = rectS.width * src.cols * 1.0 / 400 + 2;
rectL.height = rectS.height * src.cols * 1.0 / 400 + 2;
VecRect.push_back(rectS);
}
}
}
//排序
sort(VecRect.begin(),VecRect.end(),sortbyY );
/*SortRect(VecRect);*/
imgProc(src, VecRect);
VecRectLast = mergeRect(150, VecRect);
for (auto it = VecRectLast.begin(); it != VecRectLast.end(); ++it)
{
cout<<*it<<endl;
}
imshow("src", src);
waitKey(0);
return 0;
}