OpenCV image Comparison And Similarity in Android - android

I'm OpenCV learner. I was trying Image Comparison. I have used OpenCV 2.4.13.3
I have these two images 1.jpg and cam1.jpg.
When I use the following command in openCV
File sdCard = Environment.getExternalStorageDirectory();
String path1, path2;
path1 = sdCard.getAbsolutePath() + "/1.jpg";
path2 = sdCard.getAbsolutePath() + "/cam1.jpg";
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.BRIEF);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
Mat img1 = Highgui.imread(path1);
Mat img2 = Highgui.imread(path2);
Mat descriptors1 = new Mat();
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
extractor.compute(img1, keypoints1, descriptors1);
//second image
// Mat img2 = Imgcodecs.imread(path2);
Mat descriptors2 = new Mat();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector.detect(img2, keypoints2);
extractor.compute(img2, keypoints2, descriptors2);
//matcher image descriptors
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1,descriptors2,matches);
// Filter matches by distance
MatOfDMatch filtered = filterMatchesByDistance(matches);
int total = (int) matches.size().height;
int Match= (int) filtered.size().height;
Log.d("LOG", "total:" + total + " Match:"+Match);
Method filterMatchesByDistance
static MatOfDMatch filterMatchesByDistance(MatOfDMatch matches){
List<DMatch> matches_original = matches.toList();
List<DMatch> matches_filtered = new ArrayList<DMatch>();
int DIST_LIMIT = 30;
// Check all the matches distance and if it passes add to list of filtered matches
Log.d("DISTFILTER", "ORG SIZE:" + matches_original.size() + "");
for (int i = 0; i < matches_original.size(); i++) {
DMatch d = matches_original.get(i);
if (Math.abs(d.distance) <= DIST_LIMIT) {
matches_filtered.add(d);
}
}
Log.d("DISTFILTER", "FIL SIZE:" + matches_filtered.size() + "");
MatOfDMatch mat = new MatOfDMatch();
mat.fromList(matches_filtered);
return mat;
}
Log
total:122 Match:30
As we can see from the log match is 30.
But as we can see both images have same visual element (in).
How can I get match=90 using openCV?
It would be great if somebody can help with code snippet.
If using opencv it is not possible then what are the other
alternatives we can look for?

But as we can see both images have same visual element (in).
So, we should compare not whole images, but "same visual element" on it. You can improve Match value more if you do not compare the "template" and "camera" images themselves, but processed same way (converted to binary black/white, for example) "template" and "camera" images. For example, try to find blue (background of template logo) square on both ("template" and "camera") images and compare that squares (Region Of Interest). The code may be something like that:
Bitmap bmImageTemplate = <get your template image Bitmap>;
Bitmap bmTemplate = findLogo(bmImageTemplate); // process template image
Bitmap bmImage = <get your camera image Bitmap>;
Bitmap bmLogo = findLogo(bmImage); // process camera image same way
compareBitmaps(bmTemplate, bmLogo);
where
private Bitmap findLogo(Bitmap sourceBitmap) {
Bitmap roiBitmap = null;
Mat sourceMat = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);
Utils.bitmapToMat(sourceBitmap, sourceMat);
Mat roiTmp = sourceMat.clone();
final Mat hsvMat = new Mat();
sourceMat.copyTo(hsvMat);
// convert mat to HSV format for Core.inRange()
Imgproc.cvtColor(hsvMat, hsvMat, Imgproc.COLOR_RGB2HSV);
Scalar lowerb = new Scalar(85, 50, 40); // lower color border for BLUE
Scalar upperb = new Scalar(135, 255, 255); // upper color border for BLUE
Core.inRange(hsvMat, lowerb, upperb, roiTmp); // select only blue pixels
// find contours
List<MatOfPoint> contours = new ArrayList<>();
List<Rect> squares = new ArrayList<>();
Imgproc.findContours(roiTmp, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
// find appropriate bounding rectangles
for (MatOfPoint contour : contours) {
MatOfPoint2f areaPoints = new MatOfPoint2f(contour.toArray());
RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints);
double rectangleArea = boundingRect.size.area();
// test min ROI area in pixels
if (rectangleArea > 400) {
Point rotated_rect_points[] = new Point[4];
boundingRect.points(rotated_rect_points);
Rect rect = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points));
double aspectRatio = rect.width > rect.height ?
(double) rect.height / (double) rect.width : (double) rect.width / (double) rect.height;
if (aspectRatio >= 0.9) {
squares.add(rect);
}
}
}
Mat logoMat = extractSquareMat(roiTmp, getBiggestSquare(squares));
roiBitmap = Bitmap.createBitmap(logoMat.cols(), logoMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(logoMat, roiBitmap);
return roiBitmap;
}
method extractSquareMat() just extract Region of Interest (logo) from whole image
public static Mat extractSquareMat(Mat sourceMat, Rect rect) {
Mat squareMat = null;
int padding = 50;
if (rect != null) {
Rect truncatedRect = new Rect((int) rect.tl().x + padding, (int) rect.tl().y + padding,
rect.width - 2 * padding, rect.height - 2 * padding);
squareMat = new Mat(sourceMat, truncatedRect);
}
return squareMat ;
}
and compareBitmaps() just wrapper for your code:
private void compareBitmaps(Bitmap bitmap1, Bitmap bitmap2) {
Mat mat1 = new Mat(bitmap1.getWidth(), bitmap1.getHeight(), CvType.CV_8UC3);
Utils.bitmapToMat(bitmap1, mat1);
Mat mat2 = new Mat(bitmap2.getWidth(), bitmap2.getHeight(), CvType.CV_8UC3);
Utils.bitmapToMat(bitmap2, mat2);
compareMats(mat1, mat2);
}
your code as method:
private void compareMats(Mat img1, Mat img2) {
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.BRIEF);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
Mat descriptors1 = new Mat();
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
extractor.compute(img1, keypoints1, descriptors1);
//second image
// Mat img2 = Imgcodecs.imread(path2);
Mat descriptors2 = new Mat();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector.detect(img2, keypoints2);
extractor.compute(img2, keypoints2, descriptors2);
//matcher image descriptors
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1,descriptors2,matches);
// Filter matches by distance
MatOfDMatch filtered = filterMatchesByDistance(matches);
int total = (int) matches.size().height;
int Match= (int) filtered.size().height;
Log.d("LOG", "total:" + total + " Match:" + Match);
}
static MatOfDMatch filterMatchesByDistance(MatOfDMatch matches){
List<DMatch> matches_original = matches.toList();
List<DMatch> matches_filtered = new ArrayList<DMatch>();
int DIST_LIMIT = 30;
// Check all the matches distance and if it passes add to list of filtered matches
Log.d("DISTFILTER", "ORG SIZE:" + matches_original.size() + "");
for (int i = 0; i < matches_original.size(); i++) {
DMatch d = matches_original.get(i);
if (Math.abs(d.distance) <= DIST_LIMIT) {
matches_filtered.add(d);
}
}
Log.d("DISTFILTER", "FIL SIZE:" + matches_filtered.size() + "");
MatOfDMatch mat = new MatOfDMatch();
mat.fromList(matches_filtered);
return mat;
}
As result for resized (scaled for 50%) images saved from your question result is:
D/DISTFILTER: ORG SIZE:237
D/DISTFILTER: FIL SIZE:230
D/LOG: total:237 Match:230
NB! This is a quick and dirty example just to demonstrate approach only for given template.
P.S. getBiggestSquare() can be like that (based on compare by area):
public static Rect getBiggestSquare(List<Rect> squares) {
Rect biggestSquare = null;
if (squares != null && squares.size() >= 1) {
Rect square;
double maxArea;
int ixMaxArea = 0;
square = squares.get(ixMaxArea);
maxArea = square.area();
for (int ix = 1; ix < squares.size(); ix++) {
square = squares.get(ix);
if (square.area() > maxArea) {
maxArea = square.area();
ixMaxArea = ix;
}
}
biggestSquare = squares.get(ixMaxArea);
}
return biggestSquare;
}

Related

Comparing two images in android OpenCV usning ORB

I am new to OpenCV and I am trying to write an android code using OpenCV to compare two images for similarities, for my example i loaded two images from Drawable folder as you see in the code, but i am not able to complete the code in order to get a percentage of matching between images and to set a threshold or something? so please can any one help me solving my issue, thank you in advance. below is my Code:
public class MainActivity extends AppCompatActivity {
//TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.loadLibrary("opencv_java3");
// textView =(TextView)findViewById(R.id.textView);
Mat m1 = Imgcodecs.imread(ResourcesCompat.getDrawable(getResources(), R.drawable.image1, null).toString());
Mat m2 = Imgcodecs.imread(ResourcesCompat.getDrawable(getResources(), R.drawable.image2, null).toString());
//Imgproc.cvtColor(m1, m1, Imgproc.COLOR_RGB2BGRA);
//Imgproc.cvtColor(m2, m2, Imgproc.COLOR_RGB2BGRA);
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(m1, keypoints1);
FeatureDetector detector2 = FeatureDetector.create(FeatureDetector.ORB);
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector2.detect(m2, keypoints2);
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
Mat descriptors1 = new Mat();
extractor.compute(m1, keypoints1, descriptors1);
DescriptorExtractor extractor2 = DescriptorExtractor.create(DescriptorExtractor.ORB);
Mat descriptors2 = new Mat();
extractor2.compute(m2, keypoints2, descriptors2);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1, descriptors2, matches);
List<DMatch> matchesList = matches.toList();
double maxDistance = 0;
double minDistance = 1000;
int rowCount = matchesList.size();
for (int i = 0; i < rowCount; i++)
{
double dist = matchesList.get(i).distance;
if (dist < minDistance) minDistance = dist;
if (dist > maxDistance) maxDistance = dist;
}
List<DMatch> goodMatchesList = new ArrayList<DMatch>();
double upperBound = 1.6 * minDistance;
for (int i = 0; i < rowCount; i++)
{
if (matchesList.get(i).distance <= upperBound)
{
goodMatchesList.add(matchesList.get(i));
}
}
MatOfDMatch goodMatches = new MatOfDMatch();
goodMatches.fromList(goodMatchesList);
}
}

How to compare 2 images in android using opencv?

I am very new to android and openCV, I'M working on "Android application: plant disease Analyzer".
Below is my workflow:
1.I have static plant diseases in my gallery
2.End-user can capture an plant disease and submit to my application.
3.I want to compare the processed image with my gallery(Diseases) to get the most similar disease
Can any one tell me What will be the best algorithm to use?,
I have been searching on google but no luck,I tried with
below code snippet, which I tried using openCV :
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap camerabitmap = BitmapFactory.decodeFile(cameraimage,
bmOptions);
Bitmap galareybitmap =
BitmapFactory.decodeFile(galImage.getAbsolutePath(), bmOptions);
private double imageProcessing(Bitmap cameraimage,Bitmap
galimagebitmap,String galimagename) throws IOException {
Mat img1 = new Mat();
Utils.bitmapToMat(cameraimage, img1);
Mat img2 = new Mat();
Utils.bitmapToMat(gallimagebitmap, img2);
Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGBA2GRAY);
Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGBA2GRAY);
img1.convertTo(img1, CvType.CV_32F);
img2.convertTo(img2, CvType.CV_32F);
//Log.d("ImageComparator", "img1:"+img1.rows()+"x"+img1.cols()+" img2:"+img2.rows()+"x"+img2.cols());
Mat hist1 = new Mat();
Mat hist2 = new Mat();
MatOfInt histSize = new MatOfInt(180);
MatOfInt channels = new MatOfInt(0);
ArrayList<Mat> bgr_planes1= new ArrayList<Mat>();
ArrayList<Mat> bgr_planes2= new ArrayList<Mat>();
Core.split(img1, bgr_planes1);
Core.split(img2, bgr_planes2);
MatOfFloat histRanges = new MatOfFloat(0f, 256f);
boolean accumulate = false;
Imgproc.calcHist(bgr_planes1, channels, new Mat(), hist1, histSize, histRanges);
Core.normalize(hist1, hist1, 0, hist1.rows(), Core.NORM_MINMAX, -1, new Mat());
Imgproc.calcHist(bgr_planes2, channels, new Mat(), hist2, histSize, histRanges);
Core.normalize(hist2, hist2, 0, hist2.rows(), Core.NORM_MINMAX, -1, new Mat());
/ img1.convertTo(img1, CvType.CV_32F);
// img2.convertTo(img2, CvType.CV_32F);
hist1.convertTo(hist1, CvType.CV_32F);
hist2.convertTo(hist2, CvType.CV_32F);
return Imgproc.compareHist(hist1, hist2,3);
}
I tried with template matching also in opencv
int match_method=Imgproc.TM_CCOEFF_NORMED;
Mat temp = Imgcodecs.imread(tempim,Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE );
Mat img = Imgcodecs.imread(sourceim,Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE
);
Size sz = new Size(200, 200);
Mat resizeimage = new Mat();
Imgproc.resize(img, resizeimage, sz);
Mat sourceimage = resizeimage;
Mat resizeimage2 = new Mat();
Imgproc.resize(temp, resizeimage2, sz);
Mat templateimage = resizeimage2;
int result_cols = sourceimage.cols() - templateimage.cols() + 1;
int result_rows = sourceimage.rows() - templateimage.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
Imgproc.matchTemplate(sourceimage,templateimage, result, match_method);
//Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
Imgproc.threshold(result, result,0.1,1,Imgproc.THRESH_TOZERO);
Point matchLoc,maxLoc,minLoc;
Core.MinMaxLocResult mmr;
boolean iterate = true;
double minlocvalue,maxlocvalue,minminvalue,maxmaxvalue;
while(true){
mmr = Core.minMaxLoc(result);
if (match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED) {
matchLoc = mmr.minLoc;
minminvalue = mmr.minVal; // test
} else {
matchLoc = mmr.maxLoc;
maxmaxvalue = mmr.minVal; // test
}
Log.d(TAG, "mmr.maxVal : "+mmr.maxVal);
if(mmr.maxVal >=0.2)
{
Log.d(TAG, "imagemathed..");
Imgproc.rectangle(sourceimage, matchLoc, new Point(matchLoc.x + templateimage.cols(),
matchLoc.y + templateimage.rows()), new Scalar(0, 255, 0));
Imgcodecs.imwrite(outFile, img);
Mat image = Imgcodecs.imread(outFile);
try {
Bitmap bm = Bitmap.createBitmap(image.cols(), image.rows(), Bitmap.Config.RGB_565);
Utils.matToBitmap(image, bm);
System.out.println("MinVal "+bm);
}catch(Exception e){
e.printStackTrace();
}
return true;
}else {
Log.d(TAG, "image not mathced..");
return false;
}
}
But every time I'M not getting the proper output, fault images are coming in the output.Please help me out, AM I following right approach, If not can some one suggest me which approach i have to follow.

Android Paper Detection using OpenCV

I am trying to implement Paper detection through OpenCV. I am able to understand the concept of how can I get it,
Input-> Canny-> Blur-> Find Conture-> Search (closed)Quadrilateral-> Draw Conture
but still, I am new to OpenCV programming. So having issues in implementing it. I was able to find help through this answer
Android OpenCV Paper Sheet detection
but it's drawing contour on every possible lining. Here is the code I am trying to implement.
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
Imgproc.drawContours(mRgba,findContours(mRgba), 0, new Scalar(0 , 255, 0), 5);
return mRgba;
}
public static class Quadrilateral {
public MatOfPoint contour;
public Point[] points;
public Quadrilateral(MatOfPoint contour, Point[] points) {
this.contour = contour;
this.points = points;
}
}
public static Quadrilateral findDocument( Mat inputRgba ) {
ArrayList<MatOfPoint> contours = findContours(inputRgba);
Quadrilateral quad = getQuadrilateral(contours);
return quad;
}
private static ArrayList<MatOfPoint> findContours(Mat src) {
double ratio = src.size().height / 500;
int height = Double.valueOf(src.size().height / ratio).intValue();
int width = Double.valueOf(src.size().width / ratio).intValue();
Size size = new Size(width,height);
Mat resizedImage = new Mat(size, CvType.CV_8UC4);
Mat grayImage = new Mat(size, CvType.CV_8UC4);
Mat cannedImage = new Mat(size, CvType.CV_8UC1);
Imgproc.resize(src,resizedImage,size);
Imgproc.cvtColor(resizedImage, grayImage, Imgproc.COLOR_RGBA2GRAY, 4);
Imgproc.GaussianBlur(grayImage, grayImage, new Size(5, 5), 0);
Imgproc.Canny(grayImage, cannedImage, 75, 200);
ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
Imgproc.findContours(cannedImage, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
hierarchy.release();
Collections.sort(contours, new Comparator<MatOfPoint>() {
#Override
public int compare(MatOfPoint lhs, MatOfPoint rhs) {
return Double.valueOf(Imgproc.contourArea(rhs)).compareTo(Imgproc.contourArea(lhs));
}
});
resizedImage.release();
grayImage.release();
cannedImage.release();
return contours;
}
private static Quadrilateral getQuadrilateral(ArrayList<MatOfPoint> contours) {
for ( MatOfPoint c: contours ) {
MatOfPoint2f c2f = new MatOfPoint2f(c.toArray());
double peri = Imgproc.arcLength(c2f, true);
MatOfPoint2f approx = new MatOfPoint2f();
Imgproc.approxPolyDP(c2f, approx, 0.02 * peri, true);
Point[] points = approx.toArray();
// select biggest 4 angles polygon
if (points.length == 4) {
Point[] foundPoints = sortPoints(points);
return new Quadrilateral(c, foundPoints);
}
}
return null;
}
private static Point[] sortPoints(Point[] src) {
ArrayList<Point> srcPoints = new ArrayList<>(Arrays.asList(src));
Point[] result = { null , null , null , null };
Comparator<Point> sumComparator = new Comparator<Point>() {
#Override
public int compare(Point lhs, Point rhs) {
return Double.valueOf(lhs.y + lhs.x).compareTo(rhs.y + rhs.x);
}
};
Comparator<Point> diffComparator = new Comparator<Point>() {
#Override
public int compare(Point lhs, Point rhs) {
return Double.valueOf(lhs.y - lhs.x).compareTo(rhs.y - rhs.x);
}
};
// top-left corner = minimal sum
result[0] = Collections.min(srcPoints, sumComparator);
// bottom-right corner = maximal sum
result[2] = Collections.max(srcPoints, sumComparator);
// top-right corner = minimal diference
result[1] = Collections.min(srcPoints, diffComparator);
// bottom-left corner = maximal diference
result[3] = Collections.max(srcPoints, diffComparator);
return result;
}
The answer suggests that I should use Quadrilateral Object and call it with Imgproc.drawContours(), but this function takes in ArrayList as argument where as Quadrilateral object contains MatofPoint and Point[]. Can someone help me through this..I am using OpenCV(3.3) and Android (1.5.1)?
Here is the sample what it should look like

Degree of similarity between two images in opencv

I'm trying to calculate the degree of similarity between two images but it gives me 0 every time.
This is my code:
public class TemplateMatching{
static void analyze(Mat image, MatOfKeyPoint keypoints, Mat descriptors){
detector.detect(image, keypoints);
extractor.compute(image, keypoints, descriptors);
}
static FeatureDetector detector= FeatureDetector.create(FeatureDetector.ORB);
static DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.BRIEF);
final static DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
static void ana(Mat image, MatOfKeyPoint keypoints, Mat descriptors){
detector.detect(image, keypoints);
extractor.compute(image, keypoints, descriptors);
}
static MatOfDMatch filterMatchesByDistance(MatOfDMatch matches){
List<DMatch> matches_original = matches.toList();
List<DMatch> matches_filtered = new ArrayList<DMatch>();
int DIST_LIMIT = 30;
// Check all the matches distance and if it passes add to list of filtered matches
Log.d("DISTFILTER", "ORG SIZE:" + matches_original.size() + "");
for (int i = 0; i < matches_original.size(); i++) {
DMatch d = matches_original.get(i);
if (Math.abs(d.distance) <= DIST_LIMIT) {
matches_filtered.add(d);
}
}
Log.d("DISTFILTER", "FIL SIZE:" + matches_filtered.size() + "");
MatOfDMatch mat = new MatOfDMatch();
mat.fromList(matches_filtered);
return mat;
}
public int comparer(Mat frame,Mat test) {
// Info to store analysis stats
int distance=0;
MatOfKeyPoint keypoints_o = new MatOfKeyPoint();
MatOfKeyPoint keypoints_t = new MatOfKeyPoint();
Mat descriptors_o = new Mat();
Mat descriptors_t = new Mat();
// Detect key points and compute descriptors for inputFrame
ana(frame, keypoints_o, descriptors_o);
ana(test, keypoints_t, descriptors_t);
// Compute matches
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors_o, descriptors_t, matches);
// Filter matches by distance
MatOfDMatch filtered = filterMatchesByDistance(matches);
// If count of matches is OK, apply homography check
distance = (int) filtered.size().height;
return (distance);
}
The distance is 0 every time. If I give the same image, it also gives me 0 for distance.

Load Image in Mat and Display after DFT process

I got a problem loading image (in list/on click) in Mat on Android, and processing with OpenCV DFT function then return result.
This is my src
MainActivity.java
public class MainActivity extends Activity {
static final String CAMERA_PIC_DIR = "/DCIM/Camera/";
ImageView iv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.my_image);
String ImageDir = Environment.getExternalStorageDirectory()
.getAbsolutePath() + CAMERA_PIC_DIR;
Intent i = new Intent(this, ListFile.class);
i.putExtra( "directory", ImageDir);
startActivityForResult(i,0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 0 && resultCode==RESULT_OK) {
String tmp = data.getExtras().getString("clickedFile");
//Bitmap ImageToChange= BitmapFactory.decodeFile(tmp);
//Bitmap bm = Bitmap.createScaledBitmap(ImageToChange, 480, 320, false);
Mat mRgba = new Mat();
mRgba = Highgui.imread(tmp);
getDFT(mRgba);
//iv.setImageBitmap(bm);
If i uncomment 2 Line of Bitmap and iv.set , image successfully load and display list image after click.
and this is getDFT method, still on MainActivity.java
private Mat getDFT(Mat singleChannel) {
singleChannel.convertTo(singleChannel, CvType.CV_64FC1);
int m = Core.getOptimalDFTSize(singleChannel.rows());
int n = Core.getOptimalDFTSize(singleChannel.cols()); // on the border
// add zero
// values
// Imgproc.copyMakeBorder(image1,
// padded, 0, m -
// image1.rows(), 0, n
Mat padded = new Mat(new Size(n, m), CvType.CV_64FC1); // expand input
// image to
// optimal size
Imgproc.copyMakeBorder(singleChannel, padded, 0, m - singleChannel.rows(), 0,
n - singleChannel.cols(), Imgproc.BORDER_CONSTANT);
List<Mat> planes = new ArrayList<Mat>();
planes.add(padded);
planes.add(Mat.zeros(padded.rows(), padded.cols(), CvType.CV_64FC1));
Mat complexI = Mat.zeros(padded.rows(), padded.cols(), CvType.CV_64FC2);
Mat complexI2 = Mat
.zeros(padded.rows(), padded.cols(), CvType.CV_64FC2);
Core.merge(planes, complexI); // Add to the expanded another plane with
// zeros
Core.dft(complexI, complexI2); // this way the result may fit in the
// source matrix
// compute the magnitude and switch to logarithmic scale
// => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
Core.split(complexI2, planes); // planes[0] = Re(DFT(I), planes[1] =
// Im(DFT(I))
Mat mag = new Mat(planes.get(0).size(), planes.get(0).type());
Core.magnitude(planes.get(0), planes.get(1), mag);// planes[0]
// =
// magnitude
Mat magI = mag;
Mat magI2 = new Mat(magI.size(), magI.type());
Mat magI3 = new Mat(magI.size(), magI.type());
Mat magI4 = new Mat(magI.size(), magI.type());
Mat magI5 = new Mat(magI.size(), magI.type());
Core.add(magI, Mat.ones(padded.rows(), padded.cols(), CvType.CV_64FC1),
magI2); // switch to logarithmic scale
Core.log(magI2, magI3);
Mat crop = new Mat(magI3, new Rect(0, 0, magI3.cols() & -2,
magI3.rows() & -2));
magI4 = crop.clone();
// rearrange the quadrants of Fourier image so that the origin is at the
// image center
int cx = magI4.cols() / 2;
int cy = magI4.rows() / 2;
Rect q0Rect = new Rect(0, 0, cx, cy);
Rect q1Rect = new Rect(cx, 0, cx, cy);
Rect q2Rect = new Rect(0, cy, cx, cy);
Rect q3Rect = new Rect(cx, cy, cx, cy);
Mat q0 = new Mat(magI4, q0Rect); // Top-Left - Create a ROI per quadrant
Mat q1 = new Mat(magI4, q1Rect); // Top-Right
Mat q2 = new Mat(magI4, q2Rect); // Bottom-Left
Mat q3 = new Mat(magI4, q3Rect); // Bottom-Right
Mat tmp = new Mat(); // swap quadrants (Top-Left with Bottom-Right)
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
q2.copyTo(q1);
tmp.copyTo(q2);
Core.normalize(magI4, magI5, 0, 255, Core.NORM_MINMAX);
Mat realResult = new Mat(magI5.size(), CvType.CV_8UC1);
magI5.convertTo(realResult, CvType.CV_8UC1);
return realResult;
}
and This is my ListFile.java
public class ListFile extends ListActivity {
private List<String> directoryEntries = new ArrayList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i = getIntent();
File directory = new File(i.getStringExtra("directory"));
if (directory.isDirectory()){
File[] files = directory.listFiles();
//sort in descending date order
Arrays.sort(files, new Comparator<File>(){
public int compare(File f1, File f2) {
return -Long.valueOf(f1.lastModified())
.compareTo(f2.lastModified());
}
});
//fill list with files
this.directoryEntries.clear();
for (File file : files){
this.directoryEntries.add(file.getPath());
}
ArrayAdapter<String> directoryList
= new ArrayAdapter<String>(this,
R.layout.file_row, this.directoryEntries);
//alphabetize entries
//directoryList.sort(null);
this.setListAdapter(directoryList);
}
}
#Override
protected void onListItemClick(ListView l, View v, int pos, long id) {
File clickedFile = new File(this.directoryEntries.get(pos));
Intent i = getIntent();
i.putExtra("clickedFile", clickedFile.toString());
setResult(RESULT_OK, i);
finish();
}
}
Android Successfully running, but after I click one of my choice image, android stopped working,
This is the Logcat ouput
W/dalvikvm(14245): No implementation found for native Lorg/opencv/core/Mat;.n_Mat:()J
D/AndroidRuntime(14245): Shutting down VM
W/dalvikvm(14245): threadid=1: thread exiting with uncaught exception (group=0x40cbb9c0)
E/AndroidRuntime(14245): FATAL EXCEPTION: main
E/AndroidRuntime(14245): java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.core.Mat.n_Mat:()J
Link Reference:
android dft got hang
Convert Opencv DFT

Categories

Resources