因此,我设法使用opencv c ++代码检测文档边框。现在,我需要裁剪该图像并使其看起来不错。
边框检测效果很好,如下图所示:
但是现在,当我尝试裁剪它时,它看起来像这样:
现在,这是我正在使用的代码:
extern "C"
JNIEXPORT void JNICALL
Java_prisca_ctest_ScanActivity_doWithMat(JNIEnv *env, jobject instance, jlong matNumber) {
//reference to the image from Java
Mat &image = *(Mat *) matNumber;
//resize image
image = GetSquareImage(image);
//add color effects for better detection
Mat gray;
cvtColor(image, gray, CV_BGR2GRAY);
GaussianBlur(gray, gray, Size(5, 5), 0);
Mat edged;
Canny(gray, edged, 75, 200);
//find contours and sort them from biggest to smallest
vector<vector<Point> > contours;
vector<Point> screenCnt;
findContours(edged, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);
// sort contours
sort(contours.begin(), contours.end(), compareContourAreas);
Rect boundRect;
//itterate over the contours and get the biggest contour for image
for (int i = (int) (contours.size() - 1); i > 0; i--) {
double peri = arcLength(Mat(contours[i]), true);
vector<Point> approx;
approxPolyDP(Mat(contours[i]), approx, 0.02 * peri, true);
if (approx.size() == 4) {
screenCnt = approx;
boundRect = boundingRect(approx);
break;
}
}
Scalar color = Scalar(0, 255, 0);
drawContours(image, Mat(screenCnt), -1, color, 5);
//crop image with boundRect
image = Mat(image, boundRect).clone();
}
Mat GetSquareImage(const cv::Mat &img, int target_width = 500) {
int width = img.cols,
height = img.rows;
cv::Mat square = cv::Mat::zeros(target_width, target_width, img.type());
int max_dim = (width >= height) ? width : height;
float scale = ((float) target_width) / max_dim;
cv::Rect roi;
if (width >= height) {
roi.width = target_width;
roi.x = 0;
roi.height = height * scale;
roi.y = (target_width - roi.height) / 2;
} else {
roi.y = 0;
roi.height = target_width;
roi.width = width * scale;
roi.x = (target_width - roi.width) / 2;
}
cv::resize(img, square(roi), roi.size());
return square;
}
extern "C"
bool compareContourAreas(std::vector<cv::Point> contour1, std::vector<cv::Point> contour2) {
double i = fabs(contourArea(cv::Mat(contour1)));
double j = fabs(contourArea(cv::Mat(contour2)));
return (i < j);
}
首先,我遵循python code的教程。他调整图片大小以获得所需的结果,当我这样做时,我的文字是不可读的,我的图像不像它应该被裁剪(裁剪它,所以没有周围的背景,只有纸等...) 。
有人有这方面的经验,如果有,有人可以帮助我吗?
答案 0 :(得分:4)
看起来您需要获取rotatedRect
而不是矩形。然后执行warpAffine
(http://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html?highlight=warpaffine)
然后使用getRotationMatrix2D
(http://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#getrotationmatrix2d)获取旋转角度,旋转图像,照常裁剪,然后旋转回正常。
答案 1 :(得分:2)
我创建了一个包含原生支持代码的git仓库,即以正确的方式裁剪图像,请在link上找到它。
如果您想出更好的解决方案,请随意编辑代码。