我正在一个项目中工作,我必须扫描目标并识别目标中的洞并且必须根据镜头进行评分。我不知道如何识别目标中的孔的确切代码。我导入了opencv库并经历了一个程序,如果我触摸它会识别相应的颜色。现在我被困在编码部分。这是给我的目标表的屏幕截图。
任何人都可以帮我解决如何继续下去的问题。提前谢谢。
答案 0 :(得分:1)
做你想做的事:
1) find white areas with max brightness;
2) find bounding contours of areas with max brightness (from p.1);
3) find bounding boxes for contours from p.2;
4) count bounding boxes.
并考虑到一些特殊情况,例如" twin"你图像上的洞。
要在Android上最简单的方法实现这些步骤,请使用OpenCV。如何将它添加到您的项目中here(您应该做一些工作:从here下载SDK并正确添加)。那么您应该看看有关在Android中使用OpenCV的一些教程,例如official。而且,您可以使用这样的代码(您的图像作为drawable
添加到演示项目的target.png
文件夹中):
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private ImageView mImageView;
private Button mProcessButton;
private Mat mSourceImageMat;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.target_image_view);
mProcessButton = (Button) findViewById(R.id.process_button);
mProcessButton.setVisibility(View.INVISIBLE);
mProcessButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
processImage();
}
});
}
private void processImage() {
try {
mSourceImageMat = Utils.loadResource(this, R.drawable.target);
Bitmap bm = Bitmap.createBitmap(mSourceImageMat.cols(), mSourceImageMat.rows(),Bitmap.Config.ARGB_8888);
final Mat mat = new Mat();
final List<Mat> channels = new ArrayList<>(3);
mSourceImageMat.copyTo(mat);
// split image channels: 0-H, 1-S, 2-V
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGB2HSV);
Core.split(mat, channels);
final Mat frameV = channels.get(2);
// find white areas with max brightness
Imgproc.threshold(frameV, frameV, 245, 255, Imgproc.THRESH_BINARY);
// find contours
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(frameV, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
// find average contour area for "twin" hole detection
double averageArea = 0;
int contoursCount = 0;
Iterator<MatOfPoint> each = contours.iterator();
while (each.hasNext()) {
averageArea += Imgproc.contourArea(each.next());
contoursCount++;
}
if (contoursCount != 0) {
averageArea /= contoursCount;
}
int holesCount = 0;
each = contours.iterator();
while (each.hasNext()) {
MatOfPoint contour = each.next();
MatOfPoint2f areaPoints = new MatOfPoint2f(contour.toArray());
RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints);
Point rect_points[] = new Point[4];
boundingRect.points(rect_points);
for(int i=0; i<4; ++i){
Imgproc.line(mSourceImageMat, rect_points[i], rect_points[(i+1)%4], new Scalar(255,0,0), 2);
}
holesCount++;
Imgproc.putText(mSourceImageMat, Integer.toString(holesCount), new Point(boundingRect.center.x + 20, boundingRect.center.y),
Core.FONT_HERSHEY_PLAIN, 1.5 ,new Scalar(255, 0, 0));
// case of "twin" hole (like 9 & 10) on image
if (Imgproc.contourArea(contour) > 1.3f * averageArea) {
holesCount++;
Imgproc.putText(mSourceImageMat, ", " + Integer.toString(holesCount), new Point(boundingRect.center.x + 40, boundingRect.center.y),
Core.FONT_HERSHEY_PLAIN, 1.5 ,new Scalar(255, 0, 0));
}
}
// convert to bitmap:
Utils.matToBitmap(mSourceImageMat, bm);
mImageView.setImageBitmap(bm);
// release
frameV.release();
mat.release();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onPostResume() {
super.onPostResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mOpenCVLoaderCallback);
}
private BaseLoaderCallback mOpenCVLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS: {
Log.i(TAG, "OpenCV loaded successfully");
mProcessButton.setVisibility(View.VISIBLE);
} break;
default: {
super.onManagerConnected(status);
} break;
}
}
};
}
如果按FIND HOLES
Button
,您会得到这样的结果
对于其他图片您应该在
中调整245, 255
值
Imgproc.threshold(frameV, frameV, 245, 255, Imgproc.THRESH_BINARY);
线。
更新:MainActivity
布局(activity_main.xml
):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ImageView
android:id="@+id/target_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
app:srcCompat="@drawable/target"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_above="@+id/process_button"/>
<Button
android:id="@+id/process_button"
android:text="Find holes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"/>
</RelativeLayout>