最近项目中需要做到图片相似度对比,搜了半天,网上有很多直接方法,但是感觉没那么靠谱,都是有弊端,eg:https://blog.csdn.net/hnulwt/article/details/43668161
https://blog.csdn.net/u010652002/article/details/72722198
上面的方法都很有价值。
觉的最靠谱的方法有两种:
一种是使用tess-two,训练自己的图片,然后做识别,但是中间遇到了写问题就没有用。
有想试试的可以访问https://blog.csdn.net/u013087553/article/details/94445109
另一种是使用openCV,里面有Imgproc.compareHist这个方法可以比较图片相似度,倒是很方便。
下面我就讲讲关于使用openCV的坑(找了半天文章,各种问题出现):
一、集成OpenCV
1.到openCV官网下载android版,我下的是最新的4.1.1。
下载完后有四个文件:
2.
导入java文件;进入file-new-import module,source directory中填入之前介绍的sdk包中的java文件,如下图所示,填好之后,会自动填入java(可以自己改名字),(如下图所示)然后点击next。
然后出现下图,直接点击finish:
然后opencv就被导入项目了,样子如下图。
然后咱们引用一下File --- Project Structure ---- app ----Dependencies,点击“+”号,选择第三个module dependcy,把java引入:
但是会报错,别着急,一项一项解决:
1.将java的build.gradle打开,修改compileSdkVersion和buildToolsVersion改成跟app里面的一致。
2.将apply plugin: 'com.android.application' 改为apply plugin: 'com.android.library'。
3.将defaultConfig删除。
4.将app的build.gradle中applicationId这句话也删掉。
现在就不会报错了。
3.在app/src/main目录下新建个jinLibs的文件夹,将sdk下native下的libs复制进来:
到这我以为可以使用了,在mainActivity初始化一下:
@Override
protected void onResume() {
super.onResume();
if(!OpenCVLoader.initDebug()){
Log.d(getClass().getName(),"Internal OpenCV library not found. Using OpenCV manger for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
}else{
Log.d(getClass().getName(),"OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS: {
Log.i("rr", "OpenCV loaded successfully");
}
break;
default: {
super.onManagerConnected(status);
}
break;
}
}
};
然后运行一下,网上都是说这样就不需要安装manager,但是我运行以后还是让安装:
我看了一下日志,如下:
上面显示"info"和"libc++"没有找到,点进去我看了一下,"info"不需要管,它里面try,catch了。我们需要解决一下"lib++"这个问题,我试了半天都没用,在defaultConfig添加了 ndk {//设置支持的SO库架构abiFilters 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'}这句话也没用,我就去掉了,但是从别人的项目拷了so文件就好了,如果你也不行到时候从我项目拷so文件就行。
因为我要做的是图片相似度对比,接下来的就是图片相似度对比的代码:
主要代码:
@Override
public void onClick(View v) {
Mat mat1 = new Mat();
Mat mat2 = new Mat();
Mat mat11 = new Mat();
Mat mat22 = new Mat();
Utils.bitmapToMat(mBitmap1, mat1);
Utils.bitmapToMat(mBitmap2, mat2);
Imgproc.cvtColor(mat1, mat11, Imgproc.COLOR_BGR2GRAY);
Imgproc.cvtColor(mat2, mat22, Imgproc.COLOR_BGR2GRAY);
comPareHist(mat11, mat22);
}
/**
* 比较来个矩阵的相似度
* @param srcMat
* @param desMat
*/
public void comPareHist(Mat srcMat,Mat desMat){
srcMat.convertTo(srcMat, CvType.CV_32F);
desMat.convertTo(desMat, CvType.CV_32F);
double target = Imgproc.compareHist(srcMat, desMat, Imgproc.CV_COMP_CORREL);
Log.e(TAG, "相似度 : ==" + target);
Toast.makeText(this, "相似度 : ==" + target, Toast.LENGTH_SHORT).show();
}
这里需要注意的一点,两张图片的尺寸一定要一样,不然会报:Error: Assertion failed (A.size == arrays[i0]->size) in init, file /build/master_pack-android/opencv/modules/core/src/matrix_iterator.cpp, line 72这个错。
项目地址:
链接:https://pan.baidu.com/s/1R1bJdPmqJkPue5pgryGAEw
提取码:us1f