我是openCV4android的初学者,如果可能的话,我想得到一些帮助。我试着用我的安卓手机摄像头检测彩色三角形、正方形或圆形,但我不知道从哪里开始。我一直在读OReilly Learning OpenCV这本书,我对OpenCV有了一些了解。
这是我想做的:
1-通过触摸屏幕获取对象的跟踪颜色(仅为HSV颜色)-我已经通过使用OpenCV4android示例中的colorblob示例做到了这一点
2-根据之前选择的颜色在相机上找到三角形、正方形或圆形等形状。
我刚刚找到了在图像中查找形状的示例。我想做的是实时使用相机进行查找。
如有任何帮助,我们将不胜感激。
致以最良好的问候,祝你今天愉快。
如果你计划为你的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
}
由于所有的操作都是使用指针完成的,所以处理它们时必须非常小心。希望这对有帮助
你为什么不使用JavaCV呢?我认为它是一个更好的选择。。你根本不必为此使用NDK。。
试试这个:http://code.google.com/p/javacv/
如果你查看OpenCV的反向投影教程,它会做你想要的(以及更多)。
背面投影:
"在统计方面,BackProjection中存储的值矩阵表示图像中的像素属于具有所选颜色的区域。"
我已经将该教程转换为OpenCV4Android(2.4.8),就像你所寻找的那样,它不使用Android NDK。你可以在Github上看到所有的代码。
您也可以查看此答案以了解更多详细信息。
虽然有点晚了,但我想为这个问题做出贡献。
1-通过以下方式获取对象的跟踪颜色(仅HSV颜色)触摸屏幕-我已经用彩色斑点完成了来自OpenCV4的示例android示例
在活动中实现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是一个垫子对象,在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,它通常是一个圆。但是,还有其他算法可以获得圆及其属性。