问题描述
我必须开发与Remove top section of image above border line to detect text document中类似的算法,但是在Java 1.8中使用JavaCV。
Python中的方法签名为
cnts = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
但是在Java中,它似乎是:
MatVector mt = new MatVector();
findContours(dst,mt,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);
我一直坚持寻找轮廓并将其从最大到最小排序。如何从最大轮廓到较低轮廓进行排序?
我的代码:
Mat image = imread(imagePath);
Mat gray = new Mat();
cvtColor(mat,gray,COLOR_BGR2GRAY);
Mat grayImg = convertToGray(mat);
GaussianBlur(grayImg,grayImg,new Size(3,3),0);
Mat dst = new Mat();
threshold(grayImg,dst,255,THRESH_BINARY + THRESH_OTSU);
// Find contours and sort for largest contour
MatVector mt = new MatVector();
findContours(dst,CHAIN_APPROX_SIMPLE);
如何从https://github.com/bytedeco/javacv/issues/1270访问轮廓建议:
// accessing contours
MatVector contours = ...
for (int i = 0; i < contours.size(); ++i) {
IntIndexer points = contours.get(i).createIndexer();
int size = (int) points.size(0); // points are stored in a Mat with a single column and multiple rows,since size(0),each element has two channels - for x and y - so the type is CV_32SC2 for integer points
for (int j = 0; j < size; ++j) {
int x = points.get(2 * j);
int y = points.get(2 * j + 1);
// do something with x and y
}
}
谢谢
解决方法
就像@ fmw42所说的那样,我重构了代码以查看contourArea()。
请参见下文
Mat mask = new Mat();
Mat gray = new Mat();
Mat denoised = new Mat();
Mat bin = new Mat();
Mat hierarchy = new Mat();
MatVector contours = new MatVector();
cvtColor(mat,gray,COLOR_BGR2GRAY);
//Normalize
GaussianBlur(gray,denoised,new Size(5,5),0);
threshold(denoised,mask,255,THRESH_BINARY_INV | THRESH_OTSU);
normalize(gray,NORM_MINMAX,-1,mask);
// Convert image to binary
threshold(gray,bin,150,THRESH_BINARY);
// Find contours
findContours(bin,contours,hierarchy,RETR_TREE,CHAIN_APPROX_NONE);
long contourCount = contours.size();
System.out.println("Countour count " + contourCount);
double maxArea = 0;
int maxAreaId = 0;
for (int i = 0; i < contourCount; ++i) {
// Calculate the area of each contour
Mat contour = contours.get(i);
double area = contourArea(contour);
if(area > maxArea){
maxAreaId = i;
maxArea = area;
}
}