I found below code for paper detection ,for the image taken from android phone's camera ,but it doesnot work on certain cases when image is at a crooked or when corners are not distinctly visible .Any help will be great or in which direction i should look further will be helpful.
fun findContours(src: Mat): ArrayList {
val grayImage: Mat
val cannedImage: Mat
val kernel: Mat = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, Size(9.0, 9.0))
val dilate: Mat
val size = Size(src.size().width, src.size().height)
grayImage = Mat(size, CvType.CV_8UC4)
cannedImage = Mat(size, CvType.CV_8UC1)
dilate = Mat(size, CvType.CV_8UC1)
Imgproc.cvtColor(src, grayImage, Imgproc.COLOR_BGR2GRAY)
Imgproc.GaussianBlur(grayImage, grayImage, Size(5.0, 5.0), 0.0)
Imgproc.threshold(grayImage, grayImage, 20.0, 255.0, Imgproc.THRESH_TRIANGLE)
Imgproc.Canny(grayImage, cannedImage, 75.0, 200.0)
Imgproc.dilate(cannedImage, dilate, kernel)
val contours = ArrayList()
val hierarchy = Mat()
Imgproc.findContours(dilate, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE)
contours.sortByDescending { p: MatOfPoint -> Imgproc.contourArea(p) }
hierarchy.release()
grayImage.release()
cannedImage.release()
kernel.release()
dilate.release()
return contours
}
private fun getCorners(contours: ArrayList, size: Size): Corners? {
val indexTo: Int
when (contours.size) {
in 0..5 -> indexTo = contours.size - 1
else -> indexTo = 4
}
for (index in 0..contours.size) {
if (index in 0..indexTo) {
val c2f = MatOfPoint2f(*contours[index].toArray())
val peri = Imgproc.arcLength(c2f, true)
val approx = MatOfPoint2f()
Imgproc.approxPolyDP(c2f, approx, 0.03 * peri, true)
//val area = Imgproc.contourArea(approx)
val points = approx.toArray().asList()
var convex = MatOfPoint()
approx.convertTo(convex, CvType.CV_32S);
// select biggest 4 angles polygon
if (points.size == 4 && Imgproc.isContourConvex(convex)) {
val foundPoints = sortPoints(points)
return Corners(foundPoints, size)
}
} else {
return null
}
}
return null
}
↧