基于OpenCV的文档扫描:优化四边形检测问题求助
相机实时文档边缘检测优化求助
背景多变且文档颜色与背景接近时,无法完整检测文档边缘,求解决方案或优化建议。
当前实现代码
预处理与Canny边缘检测
const val CLOSE_KERNEL_SIZE = 5.0 const val BLURRING_KERNEL_SIZE = 5.0 const val DILATE_KERNEL_SIZE = 5.0 val (threshold1, threshold2) = getCannyThresholds(src) Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2GRAY) Imgproc.GaussianBlur(src, src, Size(BLURRING_KERNEL_SIZE, BLURRING_KERNEL_SIZE), 3.0) Imgproc.Canny(src, destination, threshold1, threshold2) val dilateKernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, Size(DILATE_KERNEL_SIZE, DILATE_KERNEL_SIZE)) Imgproc.dilate(destination, destination, dilateKernel) val kernel = Imgproc.getStructuringElement( Imgproc.MORPH_ELLIPSE, Size(CLOSE_KERNEL_SIZE, CLOSE_KERNEL_SIZE) ) Imgproc.morphologyEx( destination, destination, Imgproc.MORPH_CLOSE, kernel, Point(-1.0, -1.0), 10 ) val preview2 = Mat(destination, Rect(0, 0, destination.width(), destination.height())) showPreview(preview2)
动态计算Canny阈值
val brightness = Core.mean(mat).`val`[0] / 255 val threshold1 = 10 / brightness val threshold2 = 40 / brightness
轮廓检测实现
private fun findLargestContours(inputMat: Mat): List<MatOfPoint>? { val mHierarchy = Mat() val mContourList: List<MatOfPoint> = ArrayList() //finding contours - as we are sorting by area anyway, we can use RETR_LIST - faster than RETR_EXTERNAL. Imgproc.findContours(inputMat, mContourList, mHierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE) // Convert the contours to their Convex Hulls i.e. removes minor nuances in the contour val mHullList: MutableList<MatOfPoint> = ArrayList() val tempHullIndices = MatOfInt() for (i in mContourList.indices) { Imgproc.convexHull(mContourList[i], tempHullIndices) mHullList.add(hull2Points(tempHullIndices, mContourList[i])) } // Release mContourList as its job is done for (c in mContourList) { c.release() } tempHullIndices.release() mHierarchy.release() if (mHullList.size != 0) { mHullList.sortWith { lhs, rhs -> Imgproc.contourArea(rhs).compareTo(Imgproc.contourArea(lhs)) } return mHullList.subList(0, min(mHullList.size, FIRST_MAX_CONTOURS)) } return null } private fun hull2Points(hull: MatOfInt, contour: MatOfPoint): MatOfPoint { val indexes = hull.toList() val points: MutableList<Point> = ArrayList() val ctrList = contour.toList() for (index in indexes) { points.add(ctrList[index]) } val point = MatOfPoint() point.fromList(points) return point }
问题表现
- 相机输入画面:

- 检测结果(绿色线条为检测到的轮廓):

目前Canny边缘检测未达预期,文档边缘无法完整被检测到。曾尝试使用Hough Lines,但文档上的文本无法去除,导致检测出大量无效线条。
内容的提问来源于stack exchange,提问作者Stoyan Milev
相关产品推荐
相关产品推荐

