how to detect the number of face in an image picture - java

I am creating an Android face detection app and when I run it on my device it always says:
"Sorry TakePic has suddenly stopped"
Here is my code for face detection and I believe that this is the source of the error:
bitmap = MediaStore.Images.Media.getBitmap(cr, selectedImage);
TextView detect = (TextView)findViewById(R.id.detect);
Bitmap maskBitmap = Bitmap.createBitmap( bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.RGB_565 );
Canvas c = new Canvas();
c.setBitmap(maskBitmap);
Paint p = new Paint();
p.setFilterBitmap(true); // possibly not nessecary as there is no scaling
c.drawBitmap(bitmap,0,0,p);
bitmap.recycle();
detectedFaces=new FaceDetector.Face[NUMBER_OF_FACES];
faceDetector=new FaceDetector(maskBitmap.getWidth(),maskBitmap.getHeight(),NUMBER_OF_FACES);
NUMBER_OF_FACE_DETECTED=faceDetector.findFaces(maskBitmap, detectedFaces);
k.setImageBitmap(bitmap);
detect.setText(NUMBER_OF_FACE_DETECTED);
Toast.makeText(MainActivity.this, selectedImage.toString(), Toast.LENGTH_LONG).show();
What would the mistake be with this code?

The best practice in such cases is to inspect LogCat view and look for exception messages to locate where your code is breaking.

Related

Android CameraX cropping media.Image?

I am using CameraX for capturing images then feeding into mlkit scanner to scan barcodes, I have created a crop rect and applied to the media.image but it doesn't seem cropping the frame...
#androidx.camera.core.ExperimentalGetImage
override fun analyze(imageProxy: ImageProxy) {
imageProxy.image ?. let {
val rotationDegrees = imageProxy.imageInfo.rotationDegrees
val imageHeight = it.height
val imageWidth = it.width
val cropRect = Rect(0, 0, imageWidth, imageHeight)
cropRect.inset(
(imageWidth/ 2),
(imageHeight/ 2)
)
it.cropRect = cropRect
val image = InputImage.fromMediaImage(it, imageProxy.imageInfo.rotationDegrees)
}
}
I tried saving the media.Image fed to scanner to a bitmap and that is not cropped too.. Let me know what I am doing wrong.
I checked this answer but it is explaining with bitmaps and I am working with media.Image
Android: How to crop images using CameraX?
ImageProxy.setCropRect()is just metadata that is passed along with the Image, and it is up to the consumer of the Image to apply the crop rect while accessing the pixels. ImageProxy.setCropRect() does not affect the crop rect of the underlying android.media.Image, it only changes the crop rect metadata for the ImageProxy instance.

Loading a bitmap with ImageDecoder from URI and adding text

In my activity, I want to modify an image to add a text on it.
The image is selected in the galery or taken with the camera and then stored in a file in a previous activity. Then the uri of that file is passed through extras.
Now I try to add a string on top of the image like so:
try {
modifyThePic(imageUri);
} catch (IOException e) {
e.printStackTrace();
}
here is the function's body:
public void modifyThePic(Uri imageUri) throws IOException {
ImageDecoder.Source source = ImageDecoder.createSource(this.getContentResolver(), imageUri);
Bitmap bitmap = ImageDecoder.decodeBitmap(source);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(10);
canvas.drawText("Some Text here", 0, 0, paint);
image.setImageBitmap(bitmap); //image is the imageView to control the result
}
The expected behaviour would be to display the image with "Some Text here" on top of it. But instead there is nothing displayed, however the app doesn't crash.
While debugging, I come across an error that appears between the
Bitmap bitmap = ImageDecoder.decodeBitmap(source);
and the
Canvas canvas = new Canvas(bitmap);
here is the error:
java.io.FileNotFoundException: No content provider: /storage/emulated/0/Android/data/com.emergence.pantherapp/files/Pictures/JPEG_20200829_181926_7510981182141824841.jpg
I suspect that I missuse the "ImageDecoder" as it's my first time using it. More precisely, I was not able to let the "decodeBitmap" method in onCreate, Android Studio was telling me that it could not be in the "main thread", I am not familiar at all with threading. Moving it in a dedicaded function fixed this but maybe am I supposed to do something else and it's the root of the problem.
My questions:
Am I using the right tools to modify the file and add the text on it ?
If yes, what do I do wrong ?
If no, what library/tools should I look into to do this task ?
Thank you,
EDIT: ADDITONAL ANSWER ELEMENTS
As both #blackapps and #rmunge pointed out, I was not getting a legit URI but instead a file path. The easy fix for my problem was to get the URI from the path using this code:
Uri realuri = Uri.fromFile(new File("insert path here")));
Additionaly to edit the bitmap, it must be made mutable which is covered here for example.
The final function to extract the bitmap from the URI and adding text on top of it is this one:
public void modifyThePic(Uri imageUri) throws IOException {
ContentResolver cr = this.getContentResolver();
InputStream input = cr.openInputStream(imageUri);
Bitmap bitmap = BitmapFactory.decodeStream(input).copy(Bitmap.Config.ARGB_8888,true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(300);
int xPos = (canvas.getWidth() / 2); //just some operations to center the text
int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)) ;
canvas.drawText("SOME TEXT TO TRY IT OUT", xPos, yPos, paint);
image.setImageBitmap(bitmap);
}
Seems your URI is wrong. It has to start with file:///

Android Opencv Why HOG descriptors are always zero?

I am stack with this problem for a couple of days. I want to make an android app that takes a picture and extracts HOG features of that image for future processing. The problem is that the code below always returns the HOG descriptors with rezo values.
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Saving a bitmap to file");
// The camera preview was automatically stopped. Start it again.
mCamera.startPreview();
mCamera.setPreviewCallback(this);
this.disableView();
Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0, data.length);
myImage = new Mat(bitmapPicture.getWidth(), bitmapPicture.getHeight(), CvType.CV_8UC1);
Utils.bitmapToMat(bitmapPicture, myImage);
Bitmap bm = Bitmap.createBitmap(myImage.cols(), myImage.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(myImage.clone(), bm);
// find the imageview and draw it!
ImageView iv = (ImageView) getRootView().findViewById(R.id.imageView);
this.setVisibility(SurfaceView.GONE);
iv.setVisibility(ImageView.VISIBLE);
Mat forHOGim = new Mat();
org.opencv.core.Size sz = new org.opencv.core.Size(64,128);
Imgproc.resize( myImage, myImage, sz );
Imgproc.cvtColor(myImage,forHOGim,Imgproc.COLOR_RGB2GRAY);
//forHOGim = myImage.clone();
MatOfFloat descriptors = new MatOfFloat(); //an empty vector of descriptors
org.opencv.core.Size winStride = new org.opencv.core.Size(64/2,128/2); //50% overlap in the sliding window
org.opencv.core.Size padding = new org.opencv.core.Size(0,0); //no padding around the image
MatOfPoint locations = new MatOfPoint(); ////an empty vector of locations, so perform full search
//HOGDescriptor hog = new HOGDescriptor();
HOGDescriptor hog = new HOGDescriptor(sz,new org.opencv.core.Size(16,16),new org.opencv.core.Size(8,8),new org.opencv.core.Size(8,8),9);
Log.i(TAG,"Constructed");
hog.compute(forHOGim , descriptors, new org.opencv.core.Size(16,16), padding, locations);
Log.i(TAG,"Computed");
Log.i(TAG,String.valueOf(hog.getDescriptorSize())+" "+descriptors.size());
Log.i(TAG,String.valueOf(descriptors.get(12,0)[0]));
double dd=0.0;
for (int i=0;i<3780;i++){
if (descriptors.get(i,0)[0]!=dd) Log.i(TAG,"NOT ZERO");
}
Bitmap bm2 = Bitmap.createBitmap(forHOGim.cols(), forHOGim.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(forHOGim,bm2);
iv.setImageBitmap(bm2);
}
So in the logcat I never get the NOT ZERO message. The problem is that whatever changes I do to this code I always have zeros in the descriptors MatOfFloat... And the strange part is, if I uncomment the HOGDescriptor hog = new HOGDescriptor(); and use that one instead of the one I am using now, my application crashes...
The rest of the code runs fine, the picture is always taken and displayed on my image view as I expect.
Any help will be appreciated.
Thanks in advance.
The problem was inside the library. When I executed the same code with OpenCV 2.4.13 for Linux and not for Android, the code worked great as expected. So I hope they will fix any problems with the HOGDescriptor for OpenCV4Android.

Android: Creating a high quality thumbnail image

I have some difficulties creating a high quality thumbnail for my captured images. I understand that there are many snippet codes and tutorials in the web to create a thumbnail. I tried them and my problem is I can't produce a high quality thumbnail image. The output is always pixelated. Any suggestion ,library or links guys? thanks in advance.
I tried this one but its low quality also.
public static Bitmap scaleBitmap(Bitmap bitmap, int wantedWidth, int wantedHeight) {
Bitmap output = Bitmap.createBitmap(wantedWidth, wantedHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Matrix m = new Matrix();
m.setScale((float) wantedWidth / bitmap.getWidth(), (float) wantedHeight / bitmap.getHeight());
canvas.drawBitmap(bitmap, m, new Paint());
return output;
}
Use RapidDecoder library. It is simple as follow:
import rapid.decoder.BitmapDecoder;
...
Bitmap bitmap = BitmapDecoder.from(getResources(), R.drawable.image)
.scale(width, height)
.useBuiltInDecoder(true)
.decode();
Don't forget to use builtin decoders if you want to scale down less than 50% and a HQ result.
Did you try this,
Bitmap src = Thumbnails.getThumbnail(getContentResolver(), ContentUris.parseId(sourceUri), Thumbnails.MINI_KIND, options);
Try this
Bitmap ThumbImage =ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(imagePath),THUMBSIZE, THUMBSIZE);
This Utility is available from API_LEVEl 8. [Source]

Generate a image with custom text in Android

I'm trying to make an app for create custom cards. I'd like to add some text over a custom background (a jpg image).
What is the best way of doing it? I'd need to show the user a preview of the card before send it to the server.
Thanks
Use below code to achieve your requirement
Bitmap src = BitmapFactory.decodeResource(getResources(), R.drawable.yourimage); // the original file yourimage.jpg i added in resources
Bitmap dest = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);
String yourText = "My custom Text adding to Image";
Canvas cs = new Canvas(dest);
Paint tPaint = new Paint();
tPaint.setTextSize(35);
tPaint.setColor(Color.BLUE);
tPaint.setStyle(Style.FILL);
cs.drawBitmap(src, 0f, 0f, null);
float height = tPaint.measureText("yY");
float width = tPaint.measureText(yourText);
float x_coord = (src.getWidth() - width)/2;
cs.drawText(yourText, x_coord, height+15f, tPaint); // 15f is to put space between top edge and the text, if you want to change it, you can
try {
dest.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File("/sdcard/ImageAfterAddingText.jpg")));
// dest is Bitmap, if you want to preview the final image, you can display it on screen also before saving
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You have to use below permission in manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
For my device the path is /sdcard to access external SD card, it may vary for other devices. Some devices may have /mnt/sdcard may be it is for internal sd cards. Just check it while before using this code.
Actually I wrote the above code for some other question, which required time stamp on photo after captured from camera. I gave you the same solution with a little modifications for your specific requirement.
I hope you can understand this. If you have any doubts regarding code feel free to ask.
I am not sure this is the best solution, but it might help you.
Step1: Create a relative layout (or any other layout) and set your image as its background.
Step2: Now add a TextView with width and height as match_parent and gravity set as top|center_horizontal.
Step3: Now add another button or any other layout control which will trigger the user confirmation. (You should place this control outside the Relative layout).
Step4: If user has confirmed the image then you can take screenshot of your relative layout via following code:
v1.setDrawingCacheEnabled(true); //v1 is the object of your Relative layout
Bitmap bm = v1.getDrawingCache();
if (bm != null) {
//TODO: write the code for saving the image.
Toast toast = Toast.makeText(YourActivity.this, "image saved",
Toast.LENGTH_LONG);
toast.show();
} else {
Toast toast = Toast.makeText(YourActivity.this,
"No image saved.", Toast.LENGTH_LONG);
toast.show();
}

Categories