c# 예제 - EmguCV:옵티컬 플로우를 사용하여 모션의 오브젝트에 윤곽을 그립니까?




라이센스 설치 (2)

먼저, Optical Flow 코드 예제를 제공 할 수 있습니다.

oldImagenewImage 이전 프레임과 현재 프레임을 유지하는 변수로 oldImage . 내 코드에서는 Image<Gray, Byte> 유형입니다.

// prep containers for x and y vectors
Image<Gray, float> velx = new Image<Gray, float>(newImage.Size);
Image<Gray, float> vely = new Image<Gray, float>(newImage.Size);

// use the Horn and Schunck dense optical flow algorithm.
OpticalFlow.HS(oldImage, newImage, true, velx, vely, 0.1d, new MCvTermCriteria(100));

// color each pixel
Image<Hsv, Byte> coloredMotion = new Image<Hsv, Byte>(newImage.Size);
for (int i = 0; i < coloredMotion.Width; i++)
{
    for (int j = 0; j < coloredMotion.Height; j++)
    {
        // Pull the relevant intensities from the velx and vely matrices
        double velxHere = velx[j, i].Intensity;
        double velyHere = vely[j, i].Intensity;

        // Determine the color (i.e, the angle)
        double degrees = Math.Atan(velyHere / velxHere) / Math.PI * 90 + 45;
        if (velxHere < 0)
        {
            degrees += 90;
        }
        coloredMotion.Data[j, i, 0] = (Byte) degrees;
        coloredMotion.Data[j, i, 1] = 255;

        // Determine the intensity (i.e, the distance)
        double intensity = Math.Sqrt(velxHere * velxHere + velyHere * velyHere) * 10;
        coloredMotion.Data[j, i, 2] = (intensity > 255) ? 255 : intensity;
    }
}
// coloredMotion is now an image that shows intensity of motion by lightness
// and direction by color.

전경을 제거하는 방법에 대한 더 큰 문제와 관련하여 :

정적 배경 이미지를 얻을 수있는 방법이 있다면 시작할 수있는 가장 좋은 방법입니다. 그런 다음 전경은 AbsDiff 메서드에 의해 감지되고 ErodeDilate 또는 Gaussian 을 사용하여 이미지를 부드럽게 한 다음 얼룩 감지를 사용합니다.

간단한 포어 그라운드 감지의 경우 광 흐름이 너무 많은 처리 (최대 8fps)가되는 반면 AbsDiff 메서드는 정확하지만 프레임 속도에는 아무런 영향을 미치지 않습니다.

윤곽선과 관련하여 크기, 위치 및 기타 순간을 찾기 만하면 위의 AbsDiff 자습서의 얼룩 감지로 Image.FindContours(...) 를 사용하는 것으로 충분합니다.

그렇지 않다면 이 튜토리얼 에서 사용 된 CvBlobDetector 클래스를 살펴보기 시작합니다. 편리한 DrawBlob 함수가 내장되어 있습니다.

C # (EmguCV 3.0 사용)에서 모션 감지를 수행하여 모션중인 오브젝트를 제거하거나 전경에서 오버레이를 그립니다.

다음은 Kinect로 수행 한 샘플 테스트입니다 (깊이 카메라이기 때문에).

EmguCV 3.0을 어떻게 시작할 수 있습니까?

  • 나는 많은 배경 제거 코드를 시도해 보았다.
  • OpticalFlow는 좋은 시작이지만 EmguCV 3.0에는 예제가 없습니다.
  • 가장 큰 얼룩을 발견하면 어떻게 그 윤곽을 찾을 수 있습니까?

누군가 나를 시작할 수 있도록 도와 줄 수 있습니까?

수정 : 2014 년 7 월 17 일

EmguCV3.0.0 RC에서 패키지 및 설명서에 OpticalFlow가 표시되지 않습니다. http://www.emgu.com/wiki/files/3.0.0-rc1/document/html/b72c032d-59ae-c36f-5e00-12f8d621dfb8.htm

DenseOpticalFlow, OpticalFlowDualTVL1 ???

이것은 AbsDiff Code입니다 :

var grayFrame = frame.Convert<Gray, Byte>();
var motionFrame = grayFrame.AbsDiff(backFrame)
                           .ThresholdBinary(new Gray(20), new Gray(255))
                           .Erode(2) 
                           .Dilate(2);

결과:

나는 하얀 동작을 어떻게 얻는 지 모른다.

이것은 블롭 코드입니다.

Image<Bgr, Byte> smoothedFrame = new Image<Bgr, byte>(frame.Size);
CvInvoke.GaussianBlur(frame, smoothedFrame, new Size(3, 3), 1); //filter out noises

Mat forgroundMask = new Mat();
fgDetector.Apply(smoothedFrame, forgroundMask);

CvBlobs blobs = new CvBlobs();
blobDetector.Detect(forgroundMask.ToImage<Gray, byte>(), blobs);
blobs.FilterByArea(400, int.MaxValue);
blobTracker.Update(blobs, 1.0, 0, 1);

foreach (var pair in blobs) {
  CvBlob b = pair.Value;
  CvInvoke.Rectangle(frame, b.BoundingBox, new MCvScalar(255.0, 255.0, 255.0), 2);
}

결과:

왜 그렇게 많은 양성 반응을 보였습니까?

이것은 MOG2 코드입니다 :

forgroundDetector.Apply(frame, forgroundMask);
motionHistory.Update(forgroundMask);
var motionMask = GetMotionMask();
Image<Bgr, Byte> motionImage = new Image<Bgr, byte>(motionMask.Size);
CvInvoke.InsertChannel(motionMask, motionImage, 0);

Rectangle[] rects;
using (VectorOfRect boundingRect = new VectorOfRect()) {
  motionHistory.GetMotionComponents(segMask, boundingRect);
  rects = boundingRect.ToArray();
}

foreach (Rectangle comp in rects) { ...

결과:

가장 큰 영역을 선택하면 어떻게 객체의 윤곽을 얻을 수 있습니까?


소스 포인트와 엔드 포인트 (단지 4가 필요함)가 있다면, 이것을 cv2.getPerspectiveTransform에 연결하고 그 결과를 cv2.warpPerspective에 사용할 수 있습니다. 당신에게 좋은 평판 결과를줍니다.





c# computer-vision emgucv