How to draw detected keypoints on an image in java/javacv? - java

Can anyone tell me that how can i detect keypoints of an image and draw that keypoints on that image in java?
I tried smt but i couldn't figure out how to draw them?
Any ideas for how should i proceed or any ideas for drawing for my code?
final IplImage image1 = cvLoadImage(
"C:/Users/Can/Desktop/panorama_image1.jpg",
CV_LOAD_IMAGE_GRAYSCALE);
final CanvasFrame canvas1 = new CanvasFrame("Image1");
canvas1.showImage(image1);
canvas1.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
SIFT sift = new SIFT();
KeyPoint keypoint1 = new KeyPoint();
sift.detect(image1, null, keypoint1);
System.out.println("Keypoints for image1: " + keypoint1.capacity());

Assuming you or anyone else still requires this, you can do the following.
Using Java, after you have computed your keypoints you can do the following using the Features2d class in OpenCV.
// draw keypoints on image
Mat outputImage = new Mat();
// Your image, keypoints, and output image
Features2d.drawKeypoints(image, keypoints, outputImage);
String filename = "keypoints.jpg";
System.out.println(String.format("Writing %s...", filename));
Highgui.imwrite(filename, outputImage);

If you or others still need an answer, I believe the possible way of doing that is
opencv_features2d.drawKeypoints(_image1, keypoint1, Mat.EMPTY);
Then you may save your _image1 to file using
ImageIO.write(_image1.getBufferedImage(), "png", new File("image1.png"));
But before that you'll have to open your image1 as a Mat object:
Mat _image1 = new Mat(image1);

Related

Image preprocessing of water meter with OpenCv Java, OCR with Tesseract

I'm trying to develop simple application (OpenCv, Tesseract and Java) where i need to get numbers from a photo of water meter. I am newbie to OpenCV and i am stuck on detection of numbers in rectangles.
So i want to achieve "00295" value as result.
Here is a example of water meter
But i am not able to achieve this result.
Steps:
Apply Gray filter
GaussianBlur filter 3x3
Sobel filter Threshold
And doing OCR with number characters allowed only
But in result i get bunch of random numbers from other labels.
Can you please give some suggestions and show way how to detect this 5 rectangles and get digits from them ?
Thanks in advance.
Here is code:
private static final int
CV_THRESH_OTSU = 8;
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat img = new Mat();
Mat imgGray = new Mat();
Mat imgGaussianBlur = new Mat();
Mat imgSobel = new Mat();
Mat imgThreshold = new Mat();
//Path to picture
String inputFilePath = "D:/OCR/test.jpg";
img = Imgcodecs.imread(inputFilePath);
Imgcodecs.imwrite("preprocess/1_True_Image.png", img);
Imgproc.cvtColor(img, imgGray, Imgproc.COLOR_BGR2GRAY);
Imgcodecs.imwrite("preprocess/2_imgGray.png", imgGray);
Imgproc.GaussianBlur(imgGray,imgGaussianBlur, new Size(3, 3),0);
Imgcodecs.imwrite("preprocess/3_imgGaussianBlur.png", imgGray);
Imgproc.Sobel(imgGaussianBlur, imgSobel, -1, 1, 0);
Imgcodecs.imwrite("preprocess/4_imgSobel.png", imgSobel);
Imgproc.threshold(imgSobel, imgThreshold, 0, 255, CV_THRESH_OTSU);
Imgcodecs.imwrite("preprocess/5_imgThreshold.png", imgThreshold);
File imageFile = new File("preprocess/5_imgThreshold.png");
Tesseract tesseract = new Tesseract();
//tessdata directory
tesseract.setDatapath("tessdata");
tesseract.setTessVariable("tessedit_char_whitelist", "0123456789");
try {
String result = tesseract.doOCR(imageFile);
System.out.println(result);
} catch (TesseractException e) {
System.err.println(e.getMessage());
}
}
}
If the position of the water filter won't change from image to image, could you just manually crop the image to your desired size? Also, after you blur the image, try using an adaptive threshold followed by canny edge detection. As a result, your image will only have the hard edges present. Then you could find contours on the image and filter through those contours till they fit the desired size that you want.

Java OpenCV convert HSV back to BGR after inRange

I'd like to create a black&white image relying on HSV filtering. However, after converting the image from BGR to HSV and applying the inRange() method, the matrix is reduced to a single channel matrix (with values either 0 or 255) and cannot be converted back to BGR.
Is there an easy way to work around this? Do I even need that step of back-conversion or can I somehow display the new image with the information I have? I'm pretty new to OpenCV and already found a very similar question but I'm still kinda confused on what to do.
Example:
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat img = Imgcodecs.imread(path);
Mat hsv = new Mat();
Mat img_new = new Mat();
Imgproc.cvtColor(img,hsv,Imgproc.COLOR_BGR2HSV);
Core.inRange(hsv, new Scalar(hue,saturation,value),new Scalar(hue,saturation,value),hsv);
Imgproc.cvtColor(hsv, img_new, Imgproc.COLOR_HSV2BGR); // This line doesn't work.
// display new image in JFrame
MatOfByte mob = new MatOfByte();
Imgcodecs.imencode(".tif", img_new, mob);
byte ba[] = mob.toArray();
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(ba));
newImgLabel.setIcon(new ImageIcon (bi));
Thank you in advance!
inRange function gives you a mask(actually, a single channel image with values 0 and 255), you can use it to select which areas you want to select.
Mat mask = new Mat();
Imgproc.cvtColor(img,hsv,Imgproc.COLOR_BGR2HSV);
Core.inRange(hsv, new Scalar(hue,saturation,value),new Scalar(hue,saturation,value),mask);
img.copyTo(img_new, mask);

How to check whether human is straight looking or not using Java with opencv

I'm using java with opencv,javacv for an image processing project. The image is not taking from the camera. I'm giving the image as below.
Mat image = Imgcodecs.imread("E:/resources/PPHOTOO/test.jpg");
and using haarcascades I'm cropping the face image too.
CascadeClassifier faceDetector = new CascadeClassifier("C:\\opencv\\haarcascades\\haarcascade_frontalface_alt.xml");
String faces;
MatOfRect faceDetections = new MatOfRect();
Mat face;
Mat crop = null;
for (int i = 0; i< faceDetections.toArray().length; i++){
faces = "Face"+i+".png";
face = image.submat(faceDetections.toArray()[i]);
crop = face.submat(4, (2*face.width())/3, 0, face.height());
Imgcodecs.imwrite(faces, face);
}
I want to find whether person is person is straight looking or not. Which means not side faces. I need to know how to find this part.
straight looking image
side face image

How to convert Ipl image to Mat image in java

I am trying to make a mood detection app in opencv, java. But there is a lag in processing the image and then displaying the emoticon. So I want to directly use the image captured , instead of copying the image to the hard disk. For that I need convert iplimage to matimage .
Try
IplImage *ipl_img;
Mat mat_img(ipl_img);
Try this
IplImage img;
bmp = Bitmap.createBitmap(img.width(), img.height(), Bitmap.Config.ARGB_8888);
bmp.copyPixelsFromBuffer(img.getByteBuffer());
Mat mROI = new Mat(new Size(img.width(), img.height()), CV_8UC4);
Utils.bitmapToMat(bmp, mROI);

How to resize an image in Java with OpenCV?

After cropping an image how can I resize it?
Mat croppedimage = cropImage( image, rect );
Mat resizeimage = croppedimage.resize( any dimension ); //need to change this line
I think, you want this.
e.g.
Mat croppedimage = cropImage(image,rect);
Mat resizeimage = new Mat();
Size sz = new Size(100,100);
Imgproc.resize( croppedimage, resizeimage, sz );
If you want to scale an image using OpenCV java then do the following:
import static org.opencv.imgproc.Imgproc.*;
import static org.opencv.imgcodecs.Imgcodecs.imread;
Main code:
Mat src = imread("imageName.jpg");
Mat resizeimage = new Mat();
Size scaleSize = new Size(300,200);
resize(src, resizeimage, scaleSize , 0, 0, INTER_AREA);
For downscaling it is recommended to use: INTER_AREA and for upscaling use INTER_CUBIC
For more details: OpenCV Ref for Resize
Please read manual for c++ method Resize it's the same to java.
You can choose a type of interpolation. In some cases it's important for a best result.
Mat croppedImage = cropImage(image,rect);
Mat resizeImage = new Mat(anyHeight, anyWidth, croppedImage.type());
int interpolation = Imgproc.INTER_CUBIC;
Imgproc.resize(croppedImage, resizeImage, resizeImage.size(), 0, 0, interpolation );

Categories

Resources