Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

android opencv optical mark recognition

I want to use opencv for OMR sheet or Bubble sheet .I dont have fix number of questions or columns in my omr sheet so i am trying to detetct rows and column (also i need to detect the title of the column)and then i can move further for filled circle detetction. I get crash on lineImgproc.boundingRect(contours[i]) .ALso i checked the intermediate result i get the row and column image ,not perfect though

P.S I am very new to opencv my approach may be incorrect ,I would be thankful for any advice.I have a similar omr sheet as in image number of questions and number of column is not fixed ,I need to identify number od=f column,number of question, column title,filled circle i.e answer so i try to detetct the lines (horizontal and vertical) image description

fun showAllBorders(paramView: Bitmap?) { // paramView = BitmapFactory.decodeFile(filename.getPath()); localMat1 = Mat() var scale = 25.0 var contourNo:Int=0 Utils.bitmapToMat(paramView, localMat1) localMat1 = Mat()

var thresMat = Mat()

var horiMat = Mat()
var grayMat = Mat()
var vertMat = Mat()
Utils.bitmapToMat(paramView, localMat1)
val imgSource: Mat = localMat1.clone()

 Imgproc.cvtColor(imgSource, grayMat, Imgproc.COLOR_RGB2GRAY)

Imgproc.adaptiveThreshold(grayMat, thresMat, 255.0, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 15, -2.0)


horiMat = thresMat.clone()
vertMat = thresMat.clone()

val horizontalSize1 = horiMat.cols().toDouble() / scale
val horizontalStructure: Mat = Imgproc.getStructuringElement(MORPH_RECT, Size(horizontalSize1, 1.0))

Imgproc.erode(horiMat, horiMat, horizontalStructure, Point(-1.0, -1.0), 1)
Imgproc.dilate(horiMat, horiMat, horizontalStructure, Point(-1.0, -1.0), 1)




val verticalSize1 = vertMat.rows().toDouble() //scale
val verticalStructure: Mat = Imgproc.getStructuringElement(MORPH_RECT, Size(1.0, verticalSize1))

Imgproc.erode(vertMat, vertMat, verticalStructure, Point(-1.0, -1.0), 1)
Imgproc.dilate(vertMat, vertMat, verticalStructure, Point(-1.0, -1.0), 4)

var mask: Mat = Mat()
var resultMat: Mat = Mat()
Core.add(horiMat, vertMat, resultMat)


var jointsMat: Mat = Mat()
Core.bitwise_and(horiMat, vertMat, jointsMat)


val contours: List<MatOfPoint> = ArrayList()
val cnts: List<MatOfPoint> = ArrayList()
val hierarchy = Mat()
var rect: Rect? = null
var rois = mutableListOf<Mat>()
var bmpList = mutableListOf<Bitmap>()


Imgproc.findContours(resultMat, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE)

for (i in contours.indices) {

    if (Imgproc.contourArea(contours[i]) < 100) {


        contourNo = i

        val contour2f = MatOfPoint2f(*contours[contourNo].toArray())
        val contours_poly = MatOfPoint2f(*contours[contourNo].toArray())

        Imgproc.approxPolyDP(contour2f, contours_poly, 3.0, true)
        val points = MatOfPoint(*contours_poly.toArray())
        var boundRect = mutableListOf<Rect>()

        boundRect[i] = Imgproc.boundingRect(contours[i]);//CRASH HERE//contours[i] is not null 


        val roi = Mat(jointsMat, boundRect[i])


        val joints_contours: List<MatOfPoint> = ArrayList()

        val hierarchy1 = Mat()



        Imgproc.findContours(roi, joints_contours, hierarchy1, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE)

        if (joints_contours.size >= 4) {

            rois.add(Mat(jointsMat, boundRect[i]))

            Imgproc.cvtColor(localMat1, localMat1, Imgproc.COLOR_GRAY2RGBA);

            Imgproc.drawContours(localMat1, contours, i, Scalar(0.0, 0.0, 255.0), 6);
            rectangle(localMat1, boundRect[i].tl(), boundRect[i].br(), Scalar(0.0, 255.0, 0.0), 1, 8, 0);
        }
    }
}


for (i in rois) {

    val analyzed = Bitmap.createBitmap(i.cols(), i.rows(), Bitmap.Config.ARGB_8888)
    Utils.matToBitmap(i, analyzed)
    bmpList.add(analyzed)

}


val analyzed = Bitmap.createBitmap(jointsMat.cols(), jointsMat.rows(), Bitmap.Config.ARGB_8888)
Utils.matToBitmap(jointsMat, analyzed)

//below shows rows and column

/*val analyzed = Bitmap.createBitmap(resultMat.cols(), resultMat.rows(), Bitmap.Config.ARGB_8888) Utils.matToBitmap(jointsMat, analyzed)

return analyzed!! */

//return

android opencv optical mark recognition

I want to use opencv for OMR sheet or Bubble sheet .I dont have fix number of questions or columns in my omr sheet so i am trying to detetct rows and column (also i need to detect the title of the column)and then i can move further for filled circle detetction. I get crash on lineImgproc.boundingRect(contours[i]) lineImgproc.boundingRect(contours[i]) .ALso i checked the intermediate result i get the row and column image ,not perfect though

P.S I am very new to opencv my approach may be incorrect ,I would be thankful for any advice.I have a similar omr sheet as in image number of questions and number of column is not fixed ,I need to identify number od=f column,number of question, column title,filled circle i.e answer so i try to detetct the lines (horizontal and vertical) vertical). image description

fun showAllBorders(paramView: Bitmap?) { // paramView = BitmapFactory.decodeFile(filename.getPath());
localMat1 = Mat()
var scale = 25.0
var contourNo:Int=0
Utils.bitmapToMat(paramView, localMat1)
localMat1 = Mat()

Mat()
var thresMat = Mat()
 var horiMat = Mat()
 var grayMat = Mat()
 var vertMat = Mat()
 Utils.bitmapToMat(paramView, localMat1)
 val imgSource: Mat = localMat1.clone()
  Imgproc.cvtColor(imgSource, grayMat, Imgproc.COLOR_RGB2GRAY)
 Imgproc.adaptiveThreshold(grayMat, thresMat, 255.0, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 15, -2.0)
 horiMat = thresMat.clone()
 vertMat = thresMat.clone()
 val horizontalSize1 = horiMat.cols().toDouble() / scale
 val horizontalStructure: Mat = Imgproc.getStructuringElement(MORPH_RECT, Size(horizontalSize1, 1.0))
 Imgproc.erode(horiMat, horiMat, horizontalStructure, Point(-1.0, -1.0), 1)
 Imgproc.dilate(horiMat, horiMat, horizontalStructure, Point(-1.0, -1.0), 1)
 val verticalSize1 = vertMat.rows().toDouble() //scale
 val verticalStructure: Mat = Imgproc.getStructuringElement(MORPH_RECT, Size(1.0, verticalSize1))
 Imgproc.erode(vertMat, vertMat, verticalStructure, Point(-1.0, -1.0), 1)
 Imgproc.dilate(vertMat, vertMat, verticalStructure, Point(-1.0, -1.0), 4)
 var mask: Mat = Mat()
 var resultMat: Mat = Mat()
 Core.add(horiMat, vertMat, resultMat)
 var jointsMat: Mat = Mat()
 Core.bitwise_and(horiMat, vertMat, jointsMat)
 val contours: List<MatOfPoint> = ArrayList()
 val cnts: List<MatOfPoint> = ArrayList()
 val hierarchy = Mat()
 var rect: Rect? = null
 var rois = mutableListOf<Mat>()
 var bmpList = mutableListOf<Bitmap>()
 Imgproc.findContours(resultMat, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE)
 for (i in contours.indices) {
 if (Imgproc.contourArea(contours[i]) < 100) {
 contourNo = i
 val contour2f = MatOfPoint2f(*contours[contourNo].toArray())
 val contours_poly = MatOfPoint2f(*contours[contourNo].toArray())
  Imgproc.approxPolyDP(contour2f, contours_poly, 3.0, true)
 val points = MatOfPoint(*contours_poly.toArray())
 var boundRect = mutableListOf<Rect>()
  boundRect[i] = Imgproc.boundingRect(contours[i]);//CRASH HERE//contours[i] is not null
 val roi = Mat(jointsMat, boundRect[i])
 val joints_contours: List<MatOfPoint> = ArrayList()
 val hierarchy1 = Mat()
  Imgproc.findContours(roi, joints_contours, hierarchy1, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE)
 if (joints_contours.size >= 4) {
 rois.add(Mat(jointsMat, boundRect[i]))
  Imgproc.cvtColor(localMat1, localMat1, Imgproc.COLOR_GRAY2RGBA);
  Imgproc.drawContours(localMat1, contours, i, Scalar(0.0, 0.0, 255.0), 6);
  rectangle(localMat1, boundRect[i].tl(), boundRect[i].br(), Scalar(0.0, 255.0, 0.0), 1, 8, 0);
 }
 }
 }
 for (i in rois) {
 val analyzed = Bitmap.createBitmap(i.cols(), i.rows(), Bitmap.Config.ARGB_8888)
 Utils.matToBitmap(i, analyzed)
 bmpList.add(analyzed)
 }
 val analyzed = Bitmap.createBitmap(jointsMat.cols(), jointsMat.rows(), Bitmap.Config.ARGB_8888)
 Utils.matToBitmap(jointsMat, analyzed)

//below shows rows and column

column /*val analyzed = Bitmap.createBitmap(resultMat.cols(), resultMat.rows(), Bitmap.Config.ARGB_8888) Utils.matToBitmap(jointsMat, analyzed)

analyzed) return analyzed!! */

*/
//return

android opencv optical mark recognition

I want to use opencv for OMR sheet or Bubble sheet .I dont have fix number of questions or columns in my omr sheet so i am trying to detetct rows and column (also i need to detect the title of the column)and then i can move further for filled circle detetction. I get crash on lineImgproc.boundingRect(contours[i]) .ALso i checked the intermediate result i get the row and column image ,not perfect though

P.S I am very new to opencv my approach may be incorrect ,I would be thankful for any advice.I have a similar omr sheet as in image number of questions and number of column is not fixed ,I need to identify number od=f column,number of question, column title,filled circle i.e answer so i try to detetct the lines (horizontal and vertical). vertical).

image description

fun showAllBorders(paramView: Bitmap?) { //   paramView = BitmapFactory.decodeFile(filename.getPath());
    localMat1 = Mat()
    var scale = 25.0
   var contourNo:Int=0
    Utils.bitmapToMat(paramView, localMat1)
    localMat1 = Mat()

    var thresMat = Mat()

    var horiMat = Mat()
    var grayMat = Mat()
    var vertMat = Mat()
    Utils.bitmapToMat(paramView, localMat1)
    val imgSource: Mat = localMat1.clone()

     Imgproc.cvtColor(imgSource, grayMat, Imgproc.COLOR_RGB2GRAY)

    Imgproc.adaptiveThreshold(grayMat, thresMat, 255.0, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 15, -2.0)


    horiMat = thresMat.clone()
    vertMat = thresMat.clone()

    val horizontalSize1 = horiMat.cols().toDouble() / scale
    val horizontalStructure: Mat = Imgproc.getStructuringElement(MORPH_RECT, Size(horizontalSize1, 1.0))

    Imgproc.erode(horiMat, horiMat, horizontalStructure, Point(-1.0, -1.0), 1)
    Imgproc.dilate(horiMat, horiMat, horizontalStructure, Point(-1.0, -1.0), 1)




    val verticalSize1 = vertMat.rows().toDouble() //scale
    val verticalStructure: Mat = Imgproc.getStructuringElement(MORPH_RECT, Size(1.0, verticalSize1))

    Imgproc.erode(vertMat, vertMat, verticalStructure, Point(-1.0, -1.0), 1)
    Imgproc.dilate(vertMat, vertMat, verticalStructure, Point(-1.0, -1.0), 4)

    var mask: Mat = Mat()
    var resultMat: Mat = Mat()
    Core.add(horiMat, vertMat, resultMat)


    var jointsMat: Mat = Mat()
    Core.bitwise_and(horiMat, vertMat, jointsMat)


    val contours: List<MatOfPoint> = ArrayList()
    val cnts: List<MatOfPoint> = ArrayList()
    val hierarchy = Mat()
    var rect: Rect? = null
    var rois = mutableListOf<Mat>()
    var bmpList = mutableListOf<Bitmap>()


    Imgproc.findContours(resultMat, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE)

    for (i in contours.indices) {

        if (Imgproc.contourArea(contours[i]) < 100) {


            contourNo = i

            val contour2f = MatOfPoint2f(*contours[contourNo].toArray())
            val contours_poly = MatOfPoint2f(*contours[contourNo].toArray())

            Imgproc.approxPolyDP(contour2f, contours_poly, 3.0, true)
            val points = MatOfPoint(*contours_poly.toArray())
            var boundRect = mutableListOf<Rect>()

            boundRect[i] = Imgproc.boundingRect(contours[i]);//CRASH HERE//contours[i] is not null 


            val roi = Mat(jointsMat, boundRect[i])


            val joints_contours: List<MatOfPoint> = ArrayList()

            val hierarchy1 = Mat()



            Imgproc.findContours(roi, joints_contours, hierarchy1, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE)

            if (joints_contours.size >= 4) {

                rois.add(Mat(jointsMat, boundRect[i]))

                Imgproc.cvtColor(localMat1, localMat1, Imgproc.COLOR_GRAY2RGBA);

                Imgproc.drawContours(localMat1, contours, i, Scalar(0.0, 0.0, 255.0), 6);
                rectangle(localMat1, boundRect[i].tl(), boundRect[i].br(), Scalar(0.0, 255.0, 0.0), 1, 8, 0);
            }
        }
    }


    for (i in rois) {

        val analyzed = Bitmap.createBitmap(i.cols(), i.rows(), Bitmap.Config.ARGB_8888)
        Utils.matToBitmap(i, analyzed)
        bmpList.add(analyzed)

    }


    val analyzed = Bitmap.createBitmap(jointsMat.cols(), jointsMat.rows(), Bitmap.Config.ARGB_8888)
    Utils.matToBitmap(jointsMat, analyzed)

//below shows rows and column

/*val analyzed = Bitmap.createBitmap(resultMat.cols(), resultMat.rows(), Bitmap.Config.ARGB_8888)
    Utils.matToBitmap(jointsMat, analyzed)

return analyzed!!
*/

    //return