Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I try to detect circle in real-time webcam using HoughCircles from Opencv (javascript)

I try to detect circle in real-time webcam so I can find the distance from the camera to circle but in output, in getting a black screen. no detection and all. But I'm getting output when I give an image as input and as output. I have posted all my program please tell me what did I miss.

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Distance Testing</title>
    <link href="js_example_style.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
    <h2>Distance Testing</h2>
    <!-- <p>
        Click <b>Start/Stop</b> button to start or stop the video.<br>
        The <b>videoInput</b> is a &lt;video&gt; element used as CamShift input.
        The <b>canvasOutput</b> is a &lt;canvas&gt; element used as CamShift output.<br>
        The code of &lt;textarea&gt; will be executed when video is started.
        You can modify the code to investigate more.
    </p> -->
    <div>
    <div class="control">

        <button id="startAndStop" disabled>Start</button></div>

        <textarea class="code" rows="29" cols="100" id="codeEditor" spellcheck="false" style="display:none">
    </textarea>
    </div>
    <p class="err" id="errorMessage"></p>
    <div>
        <table cellpadding="0" cellspacing="0" width="0" border="0">
        <tr>
            <td>
                <video id="videoInput" width="520" height="440" muted loop></video>
            </td>
            <td>
                <canvas id="canvasOutput" width="520" height="440"></canvas>
            </td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>
                <div class="caption">videoInput</div>
            </td>
            <td>
                <div class="caption">canvasOutput</div>
            </td>
            <td></td>
            <td></td>
        </tr>
        </table>
    </div>
    <script src="adapter-5.0.4.js" type="text/javascript"></script>
    <script src="utils.js" type="text/javascript"></script>
    <script id="codeSnippet" type="text/code-snippet">

    const DISTANCE_TO_OBJECT = 30;
    const RADIUS_OF_MARKER = 1.0;
    const FOCAL_LENGTH = 906.107;

    const FPS = 30;

    var video = document.getElementById('videoInput');
    var src = new cv.Mat(video.height, video.width, cv.CV_8UC4);
    let dst = cv.Mat.zeros(video.height, video.width, cv.CV_8UC1);
    var ksize = new cv.Size(4, 4);
    var anchor = new cv.Point(-1, -1);

    debugger;

    // let src = cv.imread('canvasInput');
    // let dst = cv.Mat.zeros(src.rows, src.cols, cv.CV_8U);
    let circles = new cv.Mat();
    let color = new cv.Scalar(255, 0, 0);
    cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);
    // cv.blur(src, src, ksize, anchor, cv.BORDER_DEFAULT);

    // You can try more different parameters
    cv.HoughCircles(src, circles, cv.HOUGH_GRADIENT, 1, 45, 75, 40, 0, 0);


    // draw circles
    for (let i = 0; i < circles.width; ++i) {
        let x = circles.data32F[i * 3];
        let y = circles.data32F[i * 3 + 1];
        let radius = circles.data32F[i * 3 + 2];
        let center = new cv.Point(x, y);
        cv.circle(dst, center, radius, color, 3);
        let distance = (RADIUS_OF_MARKER * FOCAL_LENGTH) / radius;

        console.log("Distance is : " + distance + " cm");

        // cv.putText(dst, "Distance is : " + distance + "cm", {x: dst.x, y: dst.y}, cv.FONT_HERSHEY_SIMPLEX, 1.0, [0, 255, 0, 255]);

        // $("#difference").html("<b> Distance is : </b>" + distance);
    }


    cv.imshow('canvasOutput', dst);
    let delay = 1000/FPS;
    src.delete(); dst.delete(); circles.delete();
    </script>
    <script type="text/javascript">
        let utils = new Utils('errorMessage');

        utils.loadCode('codeSnippet', 'codeEditor');

        let streaming = false;
        let videoInput = document.getElementById('videoInput');
        let startAndStop = document.getElementById('startAndStop');
        let canvasOutput = document.getElementById('canvasOutput');
        let canvasContext = canvasOutput.getContext('2d');

        startAndStop.addEventListener('click', () => {
            if (!streaming) {
                utils.clearError();
                utils.startCamera('qvga', onVideoStarted, 'videoInput');
            } else {
                utils.stopCamera();
                onVideoStopped();
            }
        });

        function onVideoStarted() {
            streaming = true;
            startAndStop.innerText = 'Stop';
            videoInput.width = videoInput.videoWidth;
            videoInput.height = videoInput.videoHeight;
            utils.executeCode('codeEditor');
        }

        function onVideoStopped() {
            streaming = false;
            canvasContext.clearRect(0, 0, canvasOutput.width, canvasOutput.height);
            startAndStop.innerText = 'Start';
        }

        utils.loadOpenCv(() => {
            startAndStop.removeAttribute('disabled');
        });
    </script>
    </body>
    </html>

I have attached my input screen and output screen. On output instead of the black screen, I need to detect circle which I was holding, Thank you

https://i.stack.imgur.com/nrwoD.jpg