openCV4android检测形状和颜色(HSV)

时间:2013-11-24 16:14:34

标签: android opencv

我是openCV4android的初学者,如果可能的话,我想得到一些帮助 。 我正在尝试使用我的Android手机相机检测彩色三角形,正方形或圆形,但我不知道从哪里开始。 我一直在阅读OReilly Learning OpenCV一书,我对OpenCV有了一些了解。

这是我想要的:

1-通过触摸屏幕获取对象的跟踪颜色(仅颜色HSV)        - 我已经通过使用OpenCV4android示例

中的颜色blob示例完成了此操作

2-根据之前选择的颜色在相机形状上查找三角形,正方形或圆形。

我刚刚找到了在图像中查找形状的示例。我想要的是实时使用相机。

任何帮助都将不胜感激。

祝您好运,祝您度过愉快的一天。

4 个答案:

答案 0 :(得分:6)

如果您计划为opencv实现NDK,那么您可以使用他们在OpenCV教程2 - 混合处理中使用的相同想法。

  // on camera frames call your native method

public Mat onCameraFrame(CvCameraViewFrame inputFrame)
{
mRgba = inputFrame.rgba();
Nativecleshpdetect(mRgba.getNativeObjAddr()); // native method call to perform color and object detection
// the method getNativeObjAddr gets the address of the Mat object(camera frame) and passes it to native side as long object so that you dont have to create and destroy Mat object on each frame
}
public native void Nativecleshpdetect(long matAddrRgba);

在原住民方面

JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_Nativecleshpdetect(JNIEnv*, jobject,jlong addrRgba1)
{

    Mat& mRgb1 = *(Mat*)addrRgba1;
// mRgb1 is a mat object which points to the address of the input camera frame, so all the manipulations you do here will reflect on the live camera frame  

 //once you have your mat object(i.e mRgb1 ) you can implement all the colour and shape detection algorithm you have learnt in opencv book  

}

由于所有操作都是使用指针完成的,因此必须小心处理它们。希望这有帮助

答案 1 :(得分:2)

为什么不使用JavaCV我认为它是一个更好的选择..你根本不必使用NDK ..

试试这个: http://code.google.com/p/javacv/

答案 2 :(得分:2)

如果你检查OpenCV's Back Projection tutorial它会做你正在寻找的东西(还有更多)。

背投影:

  

“在统计方面,存储在BackProjection中的值   矩阵表示图像中的像素所属的概率   具有所选颜色的区域。“

我已将该教程转换为 OpenCV4Android (2.4.8),就像您要找的那样,它不使用Android NDK。您可以看到所有code here at Github

您还可以查看this answer for more details.

答案 3 :(得分:1)

虽然有点晚了但我想为这个问题做出贡献。

  

1-获取对象的跟踪颜色(仅颜色HSV)   触摸屏幕 - 我已经通过使用颜色blob完成了这项工作   例子来自OpenCV4android示例

将OnTouchListener实施到您的活动

onTouch功能

int cols = mRgba.cols();
int rows = mRgba.rows();

int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;

int x = (int) event.getX() - xOffset;
int y = (int) event.getY() - yOffset;

Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");

if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;

Rect touchedRect = new Rect();

touchedRect.x = (x > 4) ? x - 4 : 0;
touchedRect.y = (y > 4) ? y - 4 : 0;

touchedRect.width = (x + 4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
touchedRect.height = (y + 4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;


Mat touchedRegionRgba = mRgba.submat(touchedRect);


Mat touchedRegionHsv = new Mat();
Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);

// Calculate average color of touched region
mBlobColorHsv = Core.sumElems(touchedRegionHsv);

int pointCount = touchedRect.width * touchedRect.height;
for (int i = 0; i < mBlobColorHsv.val.length; i++)
    mBlobColorHsv.val[i] /= pointCount;



mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
mColor = mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] + ", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3];
Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
        ", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");

mRGBA是一个mat对象,它是在 onCameraViewStarted 中启动的

  

mRgba =新垫(高度,宽度,CvType.CV_8UC4);

第二部分:

  

2-在相机上查找基于三角形,正方形或圆形的形状   关于之前选择的颜色。

我试图使用 approxPolyDP 找出所选的轮廓形状

MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(0).toArray());
                //Processing on mMOP2f1 which is in type MatOfPoint2f
                double approxDistance = Imgproc.arcLength(contour2f, true) * 0.02;
                Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);


                //Convert back to MatOfPoint
                MatOfPoint points = new MatOfPoint(approxCurve.toArray());

                System.out.println("points length" + points.toArray().length);

                if( points.toArray().length == 5)
                {
                    System.out.println("Pentagon");
                    mShape = "Pentagon";
                }
                else if(points.toArray().length > 5)
                {
                    System.out.println("Circle");
                    Imgproc.drawContours(mRgba, contours, 0, new Scalar(255, 255, 0, -1));
                    mShape = "Circle";
                }
                else if(points.toArray().length == 4)
                {
                    System.out.println("Square");
                    mShape = "Square";
                }
                else  if(points.toArray().length == 4)
                {
                    System.out.println("Triangle");
                    mShape = "Triangle";
                }

在我获得轮廓列表后,这是在 onCameraFrame 函数上完成的

对我来说,如果点阵的长度大于5,那通常是一个圆圈。但是还有其他算法可以获得圆及其属性。