Converting IplImage to BufferedImage to integrate - java

I'm making my own Image processing application that completely operates in BufferedImage.
Now i have stumbled upon a code on Face detection in a blog of [OpenShift.com]
Now i want to integrate that code into my own GUI application.But facing problems as the Face Detector code the image is an instance of iplImage object and for that i need to first convert the buffered image to IplImage so that the method accepts the now converted image.
Please help..
i am leaving below the Face detector code.
public class FaceDetection{
//Load haar classifier XML file
public static final String XML_FILE =
"C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml";
public static void main(String[] args){
//Load image
IplImage img = cvLoadImage("C:\\Users\\The Blue Light\\Desktop\\13.jpg");
detect(img);
}
//Detect for face using classifier XML file
public static void detect(IplImage src){
//Define classifier
CvHaarClassifierCascade cascade = new CvHaarClassifierCascade(cvLoad(XML_FILE));
CvMemStorage storage = CvMemStorage.create();
//Detect objects
CvSeq sign = cvHaarDetectObjects(
src,
cascade,
storage,
1.5,
3,
CV_HAAR_DO_CANNY_PRUNING);
cvClearMemStorage(storage);
int total_Faces = sign.total();
//Draw rectangles around detected objects
for(int i = 0; i < total_Faces; i++){
CvRect r = new CvRect(cvGetSeqElem(sign, i));
cvRectangle (
src,
cvPoint(r.x(), r.y()),
cvPoint(r.width() + r.x(), r.height() + r.y()),
CvScalar.CYAN,
2,
CV_AA,
0);
}
//Display result
cvShowImage("Result", src);
cvWaitKey(0);
}
}

IplImage image = IplImage.createFrom(yourBufferedImage);
Thanks #Marco13
exactly what i needed..

Related

Face Detection and extracting the faces using Bounding Box and creating a new Bitmap

How do I use the Rect rect = face.getBoundingBox() data to crop out the detected face from the bitmap and save it as a new bitmap. Ive attempted to construct the bitmap using rect.left etc and simply display the extracted face in imageview.. but it does not seem to work.
Also, is it possible to access the faces directly?
If I understand correctly the detector creates a List of FirebaseVisionFace, what are these listings?
How does it list a face?
Is it possible to access them?
private void processFaceDetection(final Bitmap bitmap) {
FirebaseVisionImage firebaseVisionImage = FirebaseVisionImage.fromBitmap(bitmap); //firebaseVisionImage is an object created from bitmap firebase uses to detect faces
FirebaseVisionFaceDetectorOptions firebaseVisionFaceDetectorOptions = new FirebaseVisionFaceDetectorOptions.Builder().build();
FirebaseVisionFaceDetector firebaseVisionFaceDetector = FirebaseVision.getInstance().getVisionFaceDetector(firebaseVisionFaceDetectorOptions);
firebaseVisionFaceDetector.detectInImage(firebaseVisionImage).addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() {
#Override
public void onSuccess(List<FirebaseVisionFace> firebaseVisionFaces) {
int counter = 0;
for (FirebaseVisionFace face : firebaseVisionFaces) {
Rect rect = face.getBoundingBox();
RectOverlay rectOverlay = new RectOverlay(graphicOverlay, rect);
graphicOverlay.add(rectOverlay);
Bitmap faceSaved = Bitmap.createBitmap(Math.round(Math.abs(rect.left - rect.right)), Math.round(Math.abs(rect.top - rect.bottom)), Bitmap.Config.ALPHA_8);
imageview.setImageBitmap(facesaved);
imageview.setVisibility(View.VISIBLE);
counter++;
}
ANSWER:
To use the rect data, which can be gathered using rect.toShortString(), produces 4 values for left, top, right, bottom. i.e. [280,495][796,1011]. These are created by the FirebaseVisionFaceDetector and are stored in a list (List) for each detected face.
To save the bitmap data contained within different rects(faces)
for (FirebaseVisionFace face : firebaseVisionFaces) {
Rect rect = face.getBoundingBox();
Bitmap original = Bitmap.createScaledBitmap(capturedImage, cameraView.getWidth(), cameraView.getHeight(), false); //scaled bitmap created from captured image
Bitmap faceCrop = Bitmap.createBitmap(original, rect.left, rect.top, rect.width(), rect.height()); //face cropped using rect values
faceCrop contains the face-only bitmap data contained within the parameters of the rect.
Hope this helps....

How to blur a portion of an image with JAVA

How to blur a portion of an image, to hide some privates parts like credit card informations.
I try to use ConvolveOp.class like :
float[] matrix = new float[400];
for (int i = 0; i < 400; i++)
matrix[i] = 1.0f/500.0f;
BufferedImage sourceImage = (BufferedImage) image; ;
BufferedImage destImage = null ;
BufferedImageOp op = new ConvolveOp( new Kernel(20, 20, matrix), ConvolveOp.EDGE_NO_OP, null );
BufferedImage blurredImage = op.filter(sourceImage, destImage);
it seems to work, except that the image is completely blurred.
In the case you want to focus on the application and not on the specifics of image processing, you can use an image processing framework like Marvin. Thus, you can do more with less code.
Input image:
Output image:
Source code:
import static marvin.MarvinPluginCollection.*;
public class PortionBlur {
public PortionBlur(){
// 1. Load image
MarvinImage image = MarvinImageIO.loadImage("./res/credit_card.jpg");
// 2. Create masks for each blurred region
MarvinImageMask mask1 = new MarvinImageMask(image.getWidth(), image.getHeight(), 38,170,345,24);
MarvinImageMask mask2 = new MarvinImageMask(image.getWidth(), image.getHeight(), 52,212,65,24);
MarvinImageMask mask3 = new MarvinImageMask(image.getWidth(), image.getHeight(), 196,212,65,20);
MarvinImageMask mask4 = new MarvinImageMask(image.getWidth(), image.getHeight(), 38,240,200,20);
// 3. Process Image with each mask
GaussianBlur gaussianBlur = new GaussianBlur();
gaussianBlur.load();
gaussianBlur.attributes.set("radius",15);
gaussianBlur.process(image.clone(), image, mask1);
gaussianBlur.process(image.clone(), image, mask2);
gaussianBlur.process(image.clone(), image, mask3);
gaussianBlur.process(image.clone(), image, mask4);
// 4. Save the final image
MarvinImageIO.saveImage(image, "./res/credit_card_out.jpg");
}
public static void main(String[] args) {
new PortionBlur();
System.exit(0);
}
}
Gaussian blur algorithm source code:
https://github.com/gabrielarchanjo/marvinproject/blob/master/marvinproject/dev/MarvinPlugins/src/org/marvinproject/image/blur/gaussianBlur/GaussianBlur.java
I don't know whether this can be done by changing the matrix values, but this should definitely be possible by filtering a subimage, since, according to the BufferedImage.getSubimage() documentation:
The returned BufferedImage shares the same data array as the original image.
So the original BufferedImage should change with code like this:
BufferedImage image = /* ... */;
BufferedImage subImage = image.getSubimage(10, 20, 30, 40); // x, y, width, height
new ConvolveOp(new Kernel(20, 20, matrix), ConvolveOp.EDGE_NO_OP, null).filter(subImage, subImage);
I didn't test this though, and I can imagine that filter doesn't work as expected if source and destination are the same, in which case you could use a copy of the subimage, using the solution from this question:
BufferedImage image = /* ... */;
BufferedImage dest = image.getSubimage(10, 20, 30, 40); // x, y, width, height
ColorModel cm = dest.getColorModel();
BufferedImage src = new BufferedImage(cm, dest.copyData(dest.getRaster().createCompatibleWritableRaster()), cm.isAlphaPremultiplied(), null).getSubimage(0, 0, dest.getWidth(), dest.getHeight());
new ConvolveOp(new Kernel(20, 20, matrix), ConvolveOp.EDGE_NO_OP, null).filter(src, dest);
After that, continue working with image (not subImage, src or dest!)

Drawing the shape of the detected object?

I successfully detected the upperbody of the person in a picture. But all I can do now is draw a rectangle around the upperbody. How can I trace the upperbody?, i.e. draw a line (that looks like the upperbody) around the detected upperbody. I'm working with OpenCV.
Here's some code from the detection system.
if(new File("E:\\OpenCV\\opencv\\data\\haarcascades\\haarcascade_mcs_upperbody.xml\\").isFile())
{ System.out.println("file there"); }
cascadeClassifier = new CascadeClassifier("E:\\OpenCV\\opencv\\data\\haarcascades\\haarcascade_mcs_upperbody.xml");
inputPic = Highgui.imread(picSrcDir + picName);
MatOfInt intw = new MatOfInt(1);
MatOfDouble dble = new MatOfDouble(1.05);
rect = new MatOfRect();
cascadeClassifier.detectMultiScale(inputPic, rect, intw, dble);
Scalar color = new Scalar(0, 0, 255);
System.out.println("Number Of Hits: " + rect.toArray().length);
Rect[] rectArr = rect.toArray();
System.out.println(rectArr.length);
int i=0;
for(Rect recta : rectArr){
System.out.println(rectArr[i]); i++;
Core.rectangle(inputPic, new Point(recta.x, recta.y), new Point(recta.x+recta.width, recta.y+recta.height), color);
}
Highgui.imwrite(picName, inputPic);
After detecting the people upperbody rect:
Remove the rect background, keeping just the person upperbody.
Binarize the image.
Apply morphological boundary algorithm to trace the upperbody.
Example:
OpenCV provides these algorithms. However, the example above was developed using Marvin. The source code is presented below:
public class TraceShape {
public TraceShape(){
// Load Plug-in
MarvinImagePlugin boundary = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.morphological.boundary");
// Load image
MarvinImage image = MarvinImageIO.loadImage("./res/person.jpg");
// Binarize
MarvinImage binImage = MarvinColorModelConverter.rgbToBinary(image, 245);
MarvinImageIO.saveImage(binImage, "./res/person_bin.png");
// Boundary
boundary.process(binImage.clone(), binImage);
MarvinImageIO.saveImage(binImage, "./res/person_boundary.png");
}
public static void main(String[] args) {
new TraceShape();
}
}

OpenCV/JavaCV Android Face Detection Initialization

I am working on a Face Detection Problem, I have working code that uses Androids FaceDetector to find the faces but I need to figure out a way to implement OpenCV/JavaCV functions to detect faces. This is not using a live camera, it uses a image from the gallery, I am able to retrieve that images path, but I cant seem to get the CvHaarClassifierCascade classifier, and CvMemStorage storage to initialized, if anyone cant point me in the right direction or provide some source code that initializes these variable correctly in Java.
Thanks
You could do it like this: Just provide an BufferedImage.
Alternatively load the original IplImage directly with the image path using cvLoadImage(..).
// provide an BufferedImage
BufferedImage image;
// Preload the opencv_objdetect module to work around a known bug.
Loader.load(opencv_objdetect.class);
// Path to the cascade file provided by opencv
String cascade = "../haarcascade_frontalface_alt2.xml"
CvHaarClassifierCascade cvCascade = new CvHaarClassifierCascade(cvLoad(cascade));
// create storage for face detection
CvMemStorage tempStorage = CvMemStorage.create();
// create IplImage from BufferedImage
IplImage original = IplImage.createFrom(image);
IplImage grayImage = null;
if (original.nChannels() >= 3) {
// We need a grayscale image in order to do the recognition, so we
// create a new image of the same size as the original one.
grayImage = IplImage.create(image.getWidth(), image.getHeight(),
IPL_DEPTH_8U, 1);
// We convert the original image to grayscale.
cvCvtColor(original, grayImage, CV_BGR2GRAY);
} else {
grayImage = original.clone();
}
// We detect the faces with some default params
CvSeq faces = cvHaarDetectObjects(grayImage, cvCascade,
tempStorage, 1.1, 3,
0;
// Get face rectangles
CvRect[] fArray = new CvRect[faces.total()];
for (int i = 0; i < faces.total(); i++) {
fArray[i] = new CvRect(cvGetSeqElem(faces, i));
}
// print them out
for(CvRect f: fArray){
System.out.println("x: " + f.x() + "y: " + f.y() + "width: " + f.width() + "height: " + f.height());
}
tempStorage.release();
The class definitions are basically ports to Java of the original header files in C, plus the missing functionality exposed only by the C++ API of OpenCV. you can refer this link,it includes http://code.google.com/p/javacv/
and http://geekoverdose.wordpress.com/tag/opencv-javacv-android-haarcascade-face-detection/

How to resize barcode generated by barbecue api?

I have generated the barcode using barbecue and now I want to resize the barcode as per my need. I tried with BufferedImage and then I got barcode with different size but then I get an additional black line under the barcode.
public class GenerateBarcode {
public static void main(String[] args) throws Exception {
String initialString = JOptionPane.showInputDialog("Enter the text here");
Barcode barcode = BarcodeFactory.createCode128(initialString);
BufferedImage bi = BarcodeImageHandler.getImage(barcode);
}
}
Here I want to resize "bi".
To resize any BufferedImage, you can create a new one and draw your old one on top of it with a scaling applied. For example:
double scale = 2;
BufferedImage scaledBi = new BufferedImage((int)(bi.getWidth()*scale), (int) (bi.getHeight()*scale), bi.getType());
Graphics2D g2 = scaledBi.createGraphics();
g2.drawImage(bi, 0, 0, scaledBi.getWidth(), scaledBi.getHeight(), 0, 0, bi.getWidth(), bi.getHeight(), null);
scaledBi now contains your scaled image. Note that this is not vector based, so I am not sure of the quality. To increase scaling quality, you can play with the rendering hints.
Try this code:
Barcode b = BarcodeFactory.create2of7(jTextField1.getText());
b.setBarHeight(5);
b.setBarWidth(1);

Categories

Resources