這是更好地把原來的形象,但我想從你的輪廓圖像解釋
我做了以下步驟
- 你可能需要一些噪音去除(侵蝕)
- 從這些等高線計算水平和垂直投影
- 繪製圖像上的投影,以便能夠分析與檢查表相關的投影邊界。
- 請注意,垂直投影(綠色)是如何爲您提供左右邊界的指示,以及底部和頂部紙張的水平(藍色)如何。
您只需要平滑投影並精確搜索有關確切的輪廓。 ![enter image description here](https://i.stack.imgur.com/ZUMQT.jpg)
![enter image description here](https://i.stack.imgur.com/E83jt.jpg)
,如果你認爲這是我可以共享OpenCV的C++(而不是Python)
編輯的實現代碼有用:
這是我用來使代碼水平和垂直投影,你可能需要優化它。
void HVprojection(Mat image)
{
// find the vertical projection
Mat smothedRes = image.clone();
vector<double> v_vl_proj; // holds the column sum values
double max_vl_proj_h = 0,max_vl_proj_v=0; // holds the maximum value
double average_v=0;
for(int i=0;i<image.cols;++i)
{
Mat col;
Scalar col_sum;
// get individual columns
col= image.col(i);
col_sum = sum(col); // find the sum of ith column
v_vl_proj.push_back(col_sum.val[0]); // push back to vector
if(col_sum.val[0]>max_vl_proj_v) max_vl_proj_v = col_sum.val[0];
average_v+= col_sum.val[0];
}
average_v = average_v/image.cols;
// find the horizontal projection
vector<double> h_vl_proj; // holds the row sum values
double average_h=0;
for(int i=0;i<image.rows;++i)
{
Mat row;
Scalar row_sum;
// get individual columns
row= image.row(i);
row_sum = sum(row); // find the sum of ith row
h_vl_proj.push_back(row_sum.val[0]); // push back to vector
if(row_sum.val[0]>max_vl_proj_h) max_vl_proj_h = row_sum.val[0];
average_h+= row_sum.val[0];
}
average_h = average_h/image.rows;
//******************Plotting vertical projection*******************
for(int j =1;j<image.cols;j++)
{
int y1 = int(image.rows*v_vl_proj[j-1]/max_vl_proj_v);
int y2 = int(image.rows*v_vl_proj[j]/max_vl_proj_v);
line(image,Point(j-1,y1),Point(j,y2),Scalar(255,255,255),1,8);
}
int average_y = int(image.rows*average_v/max_vl_proj_v); // zero level
line(image,Point(0,average_y),Point(image.cols,average_y),Scalar(255,255,255),1,8);
//***************Plotting horizontal projection**************
for(int j =1;j<image.rows;j++)
{
int x1 = int(0.25*image.cols*h_vl_proj[j-1]/max_vl_proj_h);
int x2 = int(0.25*image.cols*h_vl_proj[j]/max_vl_proj_h);
line(image,Point(x1,j-1),Point(x2,j),Scalar(255,0,0),1,8);
}
int average_x = int(0.25*image.cols*average_h/max_vl_proj_h);
line(image,Point(average_x,0),Point(average_x,image.rows),Scalar(255,0,0),1,8);
imshow("horizontal_projection",image);
imwrite("h_p.jpg",image);
// if you want to smooth the signal of projection in case of noisu signal
v_vl_proj = smoothing(v_vl_proj);
for(int j =1;j<image.cols;j++)
{
int y1 = int(image.rows*v_vl_proj[j-1]/max_vl_proj_v);
int y2 = int(image.rows*v_vl_proj[j]/max_vl_proj_v);
line(smothedRes,Point(j-1,y1),Point(j,y2),Scalar(0,255,0),1,8);
}
int average_y1 = int(smothedRes.rows*average_v/max_vl_proj_v); // zero level
line(smothedRes,Point(0,average_y1),Point(smothedRes.cols,average_y1),Scalar(0,255,0),1,8);
imshow("SMoothed",smothedRes);
imwrite("Vertical_projection.jpg",smothedRes);
waitKey(0);
}
爲了平穩投影信號:
vector<double> smoothing(vector<double> a)
{
//How many neighbors to smooth
int NO_OF_NEIGHBOURS=5;
vector<double> tmp=a;
vector<double> res=a;
for(int i=0;i<a.size();i++)
{
if(i+NO_OF_NEIGHBOURS+1<a.size())
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
res.at(i)+=res.at(i+j+1);
}
res.at(i)/=NO_OF_NEIGHBOURS;
}
else
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
res.at(i)+=tmp.at(i-j);
}
res.at(i)/=NO_OF_NEIGHBOURS;
}
}
return res;
}
Cound還你上傳的原始圖像?只能通過邊緣圖像獲取方框可能很困難。 – maxint 2014-12-19 01:19:23
是。沒問題!謝謝! – user1243 2014-12-19 19:57:50