我在Android上的Mat中加载图片(在列表/点击中)时出现问题,并使用OpenCV DFT函数处理然后返回结果。
这是我的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);
如果我取消注释2位线和iv.set,图像成功加载并在点击后显示列表图像。
这是getDFT方法,仍在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;
}
这是我的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已成功运行,但在点击我选择的图像之后,android停止工作, 这是Logcat输出
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
链接参考: