android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“灰度化”
android:id="@+id/textView_togray" />
android:layout_width=“match_parent” android:layout_height=“match_parent” android:id="@+id/imageView_after" /> package edu.finu.cse.opencv2; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import org.opencv.android.BaseLoaderCallback; import org.opencv.android.LoaderCallbackInterface; import org.opencv.android.OpenCVLoader; import org.opencv.android.Utils; import org.opencv.core.Mat; import org.opencv.imgproc.Imgproc; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ ImageView img_after; TextView text_togray; Bitmap srcBitmap; Bitmap grayBitmap; private static boolean flag = true; //private static boolean isFirst = true; private static final String TAG = “MainActivity”; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); img_after=(ImageView)findViewById(R.id.imageView_after); text_togray=(TextView)findViewById(R.id.textView_togray); text_togray.setOnClickListener(this); } //OpenCV库加载并初始化成功后的回调函数 private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { // TODO Auto-generated method stub switch (status){ case BaseLoaderCallback.SUCCESS: Log.i(TAG, “成功加载”); Toast toast = Toast.makeText(getApplicationContext(), “成功加载!”, Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); break; default: super.onManagerConnected(status); Log.i(TAG, “加载失败”); Toast toast1 = Toast.makeText(getApplicationContext(), “加载失败!”, Toast.LENGTH_LONG); toast1.setGravity(Gravity.CENTER, 0, 0); toast1.show(); break; } } }; public void procSrc2Gray(){ Mat rgbMat = new Mat(); Mat grayMat = new Mat(); srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.duling); grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.RGB_565); Utils.bitmapToMat(srcBitmap, rgbMat);//convert original bitmap to Mat, R G B. Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);//rgbMat to gray grayMat Utils.matToBitmap(grayMat, grayBitmap); //convert mat to bitmap Log.i(TAG, “procSrc2Gray sucess…”); } @Override public void onClick(View v) { switch(v.getId()) { case R.id.textView_togray: procSrc2Gray(); img_after.setImageBitmap(grayBitmap) ; break; } } @Override public void onResume() { super.onResume(); if (!OpenCVLoader.initDebug()) { Log.d(TAG, “Internal OpenCV library not found. Using OpenCV Manager for initialization”); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, this, mLoaderCallback); } else { Log.d(TAG, “OpenCV library found inside package. Using it!”); mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); } } } 修改项目的Manifest.xml。因为新添加了Activity,这个Activity用到了相机权限等,所以要注册权限。 package=“edu.finu.cse.opencv2”> android:allowBackup=“true” android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl=“true” android:theme="@style/AppTheme"> android:label=“MyTest” android:screenOrientation=“landscape” android:configChanges=“keyboardHidden|orientation”> android:name=“android.hardware.camera” android:required=“false” /> android:name=“android.hardware.camera.autofocus” android:required=“false” /> android:name=“android.hardware.camera.front” android:required=“false” /> android:name=“android.hardware.camera.front.autofocus” android:required=“false” /> 三.训练库 训练样本分两类:正样本和负样本。正样本是希望识别的物体的图像。负样本是其他物体的图像(不含有希望识别的物体)。正样本的图像大小应当一致,负样本不做要求,但是必须大于等于正样本图像。 负样本可以是任意图像,但是这些图像中不能包含待检测的物体。用于抠取负样本的图像文件名被列在一个文件中。这个文件是纯文本文件,文件中每行是一个文件名(包括路径和文件名)。这些图像可以是不同的尺寸,但是图像尺寸应该比训练窗口的尺寸大(比正样本大),因为这些图像将被用于抠取负样本,并将负样本缩小到训练窗口大小。 下面是一个描述文件的例子: 假如目录结构如下: /img img1.jpg img2.jpg bg.txt 则bg.txt文件中的内容将如下所示: img/img1.jpg img/img2.jpg 不管是负样本还是正样本,要想训练出识别率较高的分类器,样本数据都不会少,因此描述文件明显是不能手写的,下面是一个制作描述文件的方法。 C:\Users\Hasee>D: D:>cd D:\opencvcar\car_sample D:\opencvcar\car_sample>dir /b>text.txt 先进入存有图像的目录,然后通过输出重定向将文件名一次性存到指定的文件中。然后通过文本编辑器的替换功能在每一行的行头添加文件的路径。 正样本的描述文件中的每一行除了图像的文件名和文件路径以外,还需要提供一些参数,下面是一个例子。 D:\opencvcar\car_sample\ImgData1.bmp 1 0 0 33 33 其中,1表示该图像中希望识别的物体的数量;0,0,33,33,标示其在图像中的位置和大小的矩形为(0, 0, 33, 33)。 正样本由 opencv_createsamples 生成。opencv_createsamples 是opencv提供的创建正样本的可执行程序。 以下是生成正样本的一个批处理文件的例子, opencv_createsamples.exe -info car_list.txt -vec car_samples.vec -bg ng_data.txt -num 580 -w 33 -h 33 pause 文本编辑器的替换功能在每一行的行头添加文件的路径。 正样本的描述文件中的每一行除了图像的文件名和文件路径以外,还需要提供一些参数,下面是一个例子。 D:\opencvcar\car_sample\ImgData1.bmp 1 0 0 33 33 其中,1表示该图像中希望识别的物体的数量;0,0,33,33,标示其在图像中的位置和大小的矩形为(0, 0, 33, 33)。 正样本由 opencv_createsamples 生成。opencv_createsamples 是opencv提供的创建正样本的可执行程序。 以下是生成正样本的一个批处理文件的例子, opencv_createsamples.exe -info car_list.txt -vec car_samples.vec -bg ng_data.txt -num 580 -w 33 -h 33 pauseMainActivity.java文件:
AndroidManifest.xml文件:
效果
1.准备训练数据
负样本
正样本
正样本