【问题标题】:JavaCV/OpenCV cvDrawContours modifies original imageJavaCV/OpenCV cvDrawContours 修改原始图像
【发布时间】:2012-07-25 17:30:26
【问题描述】:

我正在尝试使用 JavaCV (OpenCV),但我对以下行为感到困惑。 我的程序很简单:

  1. 抓图
  2. 创建图像的灰度版本(保持原始图像不变)
  3. 灰度图像阈值
  4. 在灰度图像中查找轮廓(克隆图像,因为 cvFindContours 修改了图像,我们希望按原样显示)
  5. 在原始彩色图像上绘制轮廓

问题是除非我克隆grabbedImage(见注释行),否则灰度图像会被修改并在其上绘制轮廓。还有,好像在grabbedImage上画了多个轮廓。

我还尝试在循环中添加睡眠,它解决了问题。难道我多次得到相同的(修改的)grabbedImage?我检查了java参考,它是不同的,但它可以是同一个缓冲区吗?

有什么想法吗?

谢谢

package com.mdarveau.opencvtest;

import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;

import com.googlecode.javacpp.Loader;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.CvContour;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_objdetect;

public class Demo {

    public static void main( String[] args ) throws Exception {
        // Preload the opencv_objdetect module to work around a known bug.
        Loader.load( opencv_objdetect.class );

        FrameGrabber grabber = FrameGrabber.createDefault( 1 );
        grabber.start();

        IplImage grabbedImage = grabber.grab();
        int width = grabbedImage.width();
        int height = grabbedImage.height();

        IplImage grayImage = IplImage.create( width, height, IPL_DEPTH_8U, 1 );

        CvMemStorage storage = CvMemStorage.create();

        CanvasFrame filterProbe = new CanvasFrame( "Filtered", CanvasFrame.getDefaultGamma() / grabber.getGamma() );
        CanvasFrame enhancedProbe = new CanvasFrame( "Enhanced", CanvasFrame.getDefaultGamma() / grabber.getGamma() );

        while ( filterProbe.isVisible() && enhancedProbe.isVisible() && (grabbedImage = grabber.grab()) != null ) {
            cvClearMemStorage( storage );

            // Convert to grayscale image...
            cvCvtColor( grabbedImage, grayImage, CV_BGR2GRAY );
            // UNCOMMENT FIXES THE PROBLEM grabbedImage = grabbedImage.clone();

            // Let's find some contours! but first some thresholding...
            cvThreshold( grayImage, grayImage, 128, 255, CV_THRESH_BINARY );

            // To check if an output argument is null we may call either isNull() or equals(null).
            CvSeq contour = new CvSeq( null );
            // cvFindContours modifies the image so clone it first since we want to keep the grayscale version
            cvFindContours( grayImage.clone(), storage, contour, Loader.sizeof( CvContour.class ), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE );
            while ( contour != null && !contour.isNull() ) {
                if ( contour.elem_size() > 0 ) {
                    CvSeq points = cvApproxPoly( contour, Loader.sizeof( CvContour.class ), storage, CV_POLY_APPROX_DP, cvContourPerimeter( contour ) * 0.02, 0 );
                    cvDrawContours( grabbedImage, points, CvScalar.BLUE, CvScalar.BLUE, -1, 1 /*CV_FILLED*/, CV_AA );
                }
                contour = contour.h_next();
            }

            filterProbe.showImage( grayImage );
            enhancedProbe.showImage( grabbedImage );
        }
        filterProbe.dispose();
        enhancedProbe.dispose();
        grabber.stop();
    }
}

【问题讨论】:

    标签: opencv javacv


    【解决方案1】:

    这是cvFindContours() 的预期行为:

    该函数在提取轮廓的同时修改图像。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-12
      • 2021-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多