I am trying to make an AR tattoo demo app which can show tattoo on hand after user draw square on his/her hand. I tried square detection and also did GaussianBlur over detected square on hand. This things are working but how can I replace that detected part with my own tattoo image so user can see AR tattoo on his/her hand.
Here is my code :
public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
CameraBridgeViewBase cameraBridgeViewBase;
BaseLoaderCallback baseLoaderCallback;
Mat bwIMG, hsvIMG, lrrIMG, urrIMG, dsIMG, usIMG, cIMG, hovIMG;
MatOfPoint2f approxCurve;
int threshold;
RelativeLayout imageslayout;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = new ImageView(MainActivity.this);
imageslayout = findViewById(R.id.imageslayout);
threshold = 100;
cameraBridgeViewBase = (JavaCameraView) findViewById(R.id.cameraViewer);
cameraBridgeViewBase.setVisibility(SurfaceView.VISIBLE);
cameraBridgeViewBase.setCvCameraViewListener(MainActivity.this);
baseLoaderCallback = new BaseLoaderCallback(MainActivity.this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
bwIMG = new Mat();
dsIMG = new Mat();
hsvIMG = new Mat();
lrrIMG = new Mat();
urrIMG = new Mat();
usIMG = new Mat();
cIMG = new Mat();
hovIMG = new Mat();
approxCurve = new MatOfPoint2f();
cameraBridgeViewBase.enableView();
break;
default:
super.onManagerConnected(status);
break;
}
}
};
}
@Override
public void onCameraViewStarted(int width, int height) {
}
@Override
public void onCameraViewStopped() {
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat gray = inputFrame.gray();
Mat dst = inputFrame.rgba();
Imgproc.pyrDown(gray, dsIMG, new Size(gray.cols() / 2, gray.rows() / 2));
Imgproc.pyrUp(dsIMG, usIMG, gray.size());
Imgproc.Canny(usIMG, bwIMG, 0, threshold);
Imgproc.dilate(bwIMG, bwIMG, new Mat(), new Point(-1, 1), 1);
List<MatOfPoint> contours = new ArrayList<>();
cIMG = bwIMG.clone();
Imgproc.findContours(cIMG, contours, hovIMG, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
for (MatOfPoint cnt : contours) {
MatOfPoint2f curve = new MatOfPoint2f(cnt.toArray());
Imgproc.approxPolyDP(curve, approxCurve, 0.02 * Imgproc.arcLength(curve, true), true);
int numberVertices = (int) approxCurve.total();
double contourArea = Imgproc.contourArea(cnt);
if (Math.abs(contourArea) < 100) {
continue;
}
if (numberVertices >= 4 && numberVertices <= 6) {
List<Double> cos = new ArrayList<>();
for (int j = 2; j < numberVertices + 1; j++) {
cos.add(angle(approxCurve.toArray()[j % numberVertices], approxCurve.toArray()[j - 2], approxCurve.toArray()[j - 1]));
}
Collections.sort(cos);
double mincos = cos.get(0);
double maxcos = cos.get(cos.size() - 1);
if (numberVertices == 4 && mincos >= -0.1 && maxcos <= 0.3) {
setLabel(dst, "X", cnt);
}
}
}
return dst;
}
@Override
protected void onPause() {
super.onPause();
if (cameraBridgeViewBase != null) {
cameraBridgeViewBase.disableView();
}
}
@Override
protected void onResume() {
super.onResume();
if (!OpenCVLoader.initDebug()) {
Toast.makeText(getApplicationContext(), "There is a problem", Toast.LENGTH_SHORT).show();
} else {
baseLoaderCallback.onManagerConnected(BaseLoaderCallback.SUCCESS);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (cameraBridgeViewBase != null) {
cameraBridgeViewBase.disableView();
}
}
private static double angle(Point pt1, Point pt2, Point pt0) {
double dx1 = pt1.x - pt0.x;
double dy1 = pt1.y - pt0.y;
double dx2 = pt2.x - pt0.x;
double dy2 = pt2.y - pt0.y;
return (dx1 * dx2 + dy1 * dy2) / Math.sqrt((dx1 * dx1 + dy1 * dy1) * (dx2 * dx2 + dy2 * dy2) + 1e-10);
}
private void setLabel(final Mat im, String label, MatOfPoint contour) {
int fontface = Core.FONT_HERSHEY_SIMPLEX;
double scale = 3;
int thickness = 3;
int[] baseline = new int[1];
Size text = Imgproc.getTextSize(label, fontface, scale, thickness, baseline);
final Rect r = Imgproc.boundingRect(contour);
final Point pt = new Point(r.x + ((r.width - text.width) / 2), r.y + ((r.height + text.height) / 2));
Mat mask = im.submat(r);
Imgproc.GaussianBlur(mask, mask, new Size(55, 55), 55); // or any other processing
Imgproc.putText(im, label, pt, fontface, scale, new Scalar(255, 0, 0), thickness);
}
}
from Replace detected square with drawable image using opencv in java android
No comments:
Post a Comment