上个帖子里面实现了灰度图转换程序,本来是想实现“高斯模糊”算法只是程序一直有问题为了完成发帖就简化了程序。
“高斯模糊”算法,公式计算机图形学中有非常详细的介绍,我们这里通过EasyPR里面理解来说明一下。
平均模糊算法,就是将像素值替换为像素周围8个像素平均值的算法,如下图:
在平均模糊中周围像素的权值都是一样的都是1。如果周围像素的权值不一样,并且与二维的高斯分布的值一样那么就叫做高斯模糊。有兴趣的人可以自己查查什么是高斯分布值,高斯函数,权重矩阵等等知识,我们这里只是肤浅的学习概念和如何使用,有点像使用VS开发软件,我们只管知道微软提供的API如何使用就可以完成一般工作,当然搞清楚其背后的原理则是极好滴!
下面直接列出代码,只是在上个帖子的代码稍微修改而已。
MainActivity.java
- package com.example.gzh.myplatelocate;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.TextView;
- import org.opencv.android.Utils;
- import org.opencv.core.Mat;
- import static org.opencv.android.OpenCVLoader.initDebug;
- import static org.opencv.imgproc.Imgproc.COLOR_RGB2GRAY;
- import static org.opencv.imgproc.Imgproc.cvtColor;
- public class MainActivity extends AppCompatActivity {
- static String TAG = "Myplatelocate";
- ImageView show_image;
- Bitmap srcBitmap;
- Bitmap grayBitmap;
- private long mRecognizerPtr = 0;
- private static boolean flag = true;
- PlateRecognizer MyPlateRecognizer;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- // Example of a call to a native method
- TextView tv = (TextView) findViewById(R.id.sample_text);
- MyPlateRecognizer = new PlateRecognizer(this);
- tv.setText(MyPlateRecognizer.stringFromJNI());
- show_image = (ImageView) findViewById(R.id.imageView);
- show_image.setImageResource(R.drawable.heidfk640);
- findViewById(R.id.button_normal).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- //恢复
- backPic();
- }
- });
- findViewById(R.id.button_gray).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- //变灰
- // grayPic();
- Log.i(TAG, "setOnClickListener procSrc2Gray sucess...my_SobelOper");
- procSrc2Gray();
- }
- });
- }
- private void backPic(){
- show_image.setImageResource(R.drawable.heidfk640);
- }
- private void grayPic(){
- Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.heidfk640);
- int w = bmp.getWidth();
- int h = bmp.getHeight();
- int[] pixels = new int[w*h];
- bmp.getPixels(pixels, 0, w, 0, 0, w, h);
- //recall JNI
- int[] resultInt = MyPlateRecognizer.getGrayImage(pixels, w, h);
- Bitmap resultImg = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
- resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);
- show_image.setImageBitmap(resultImg);
- Log.i(TAG, "procSrc2Gray sucess...11111111111");
- }
- public void procSrc2Gray(){
- int nFalg_test = 2;
- Mat rgbMat = new Mat();
- Mat grayMat = new Mat();
- srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.heidfk640);
- grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.RGB_565);
- Utils.bitmapToMat(srcBitmap, rgbMat);//convert original bitmap to Mat, R G B.
- if(nFalg_test == 1)
- {
- String str1 = null;
- str1 = String.format("call my_CvtColor rgbMat.channels()=%d", rgbMat.channels());
- Log.i(TAG, str1);
- MyPlateRecognizer.my_CvtColor(rgbMat, grayMat, COLOR_RGB2GRAY);//rgbMat to gray grayMat
- // Then convert the processed Mat to Bitmap
- Log.i(TAG, "call my_CvtColor sucess...=2=");
- }
- else {
- String str1 = null;
- str1 = String.format("call my_SobelOper rgbMat.channels()=%d", rgbMat.channels());
- Log.i(TAG, str1);
- MyPlateRecognizer.my_SobelOper(rgbMat, grayMat, COLOR_RGB2GRAY);//rgbMat to gray grayMat
- // Then convert the processed Mat to Bitmap
- Log.i(TAG, "call my_SobelOper sucess...=2=");
- }
- Utils.matToBitmap(grayMat, grayBitmap);
- Log.i(TAG, "procSrc2Gray sucess...=3=");
- show_image.setImageBitmap(grayBitmap);
- Log.i(TAG, "procSrc2Gray sucess...");
- }
- @Override
- protected void onResume() {
- super.onResume();
- if (initDebug()) {
- Log.i(TAG, "OpenCV initialize success");
- } else {
- Log.i(TAG, "OpenCV initialize failed");
- }
- }
- }
复制代码
PlateRecognizer.java
- package com.example.gzh.myplatelocate;
- import android.content.Context;
- import android.util.Log;
- import org.opencv.core.Mat;
- /**
- * Created by gzh on 17-2-12.
- */
- public class PlateRecognizer {
- // Used to load the 'native-lib' library on application startup.
- static String TAG = "PlateRecognizer";
- static {
- System.loadLibrary("native-lib");
- // System.loadLibrary("opencv_java3");
- }
- private Context mContext;
- private String mSvmpath = "svm.xml";
- private String mAnnpath = "ann.xml";
- private boolean mRecognizerInited = false;
- private long mRecognizerPtr = 0;
- public PlateRecognizer(Context context) {
- mContext = context;
- mRecognizerPtr = initPR();
- if (0 != mRecognizerPtr) {
- mRecognizerInited = true;
- }
- }
- public void finalize() {
- uninitPR(mRecognizerPtr);
- mRecognizerPtr = 0;
- mRecognizerInited = false;
- }
- public void my_SobelOper(Mat rgbMat, Mat grayMat, int COLOR_RGB2GRAY) {
- Log.i(TAG, "my_SobelOper=1=");
- mySobelOper(mRecognizerPtr, rgbMat.getNativeObjAddr(), grayMat.getNativeObjAddr());//rgbMat to gray grayMat
- Log.i(TAG, "my_SobelOper=2=");
- }
- public void my_CvtColor(Mat rgbMat, Mat grayMat, int COLOR_RGB2GRAY) {
- Log.i(TAG, "my_CvtColor=1=");
- myCvtColor(rgbMat.getNativeObjAddr(), grayMat.getNativeObjAddr(), COLOR_RGB2GRAY);//rgbMat to gray grayMat
- Log.i(TAG, "my_CvtColor=2=");
- }
- /**
- * A native method that is implemented by the 'native-lib' native library,
- * which is packaged with this application.
- */
- public static native String stringFromJNI();
- //public static native String validate(long matAddrGr, long matAddrRgba);
- //图像处理
- private static native void myCvtColor(long thiz, long inputImage, long faces);
- public static native int[] getGrayImage(int[] pixels, int w, int h);
- public static native long initPR();
- public static native long uninitPR(long recognizerPtr);
- public static native void mySobelOper(long recognizerPtr, long inputImage, long faces);
- }
复制代码
native-lib.cpp
- #include <jni.h>
- #include <string>
- #include <stdio.h>
- #include <iostream>
- #include <string>
- #include "opencv2/opencv.hpp"
- #include <stdio.h>
- #include <iostream>
- #include <string>
- #include "platelocate.h"
- #include <android/log.h>
- #include "platelocate.h"
- using namespace easypr;
- using namespace std;
- using namespace cv;
- int m_GaussianBlurSize = 5;
- int m_MorphSizeWidth = 17;
- int m_MorphSizeHeight = 3;
- static const int DEFAULT_GAUSSIANBLUR_SIZE = 5;
- static const int SOBEL_SCALE = 1;
- static const int SOBEL_DELTA = 0;
- static const int SOBEL_DDEPTH = CV_16S;
- static const int SOBEL_X_WEIGHT = 1;
- static const int SOBEL_Y_WEIGHT = 0;
- static const int DEFAULT_MORPH_SIZE_WIDTH = 17; // 17
- static const int DEFAULT_MORPH_SIZE_HEIGHT = 3; // 3
- static const int WIDTH = 136;
- static const int HEIGHT = 36;
- static const int TYPE = CV_8UC3;
- static const int DEFAULT_VERIFY_MIN = 1; // 3
- static const int DEFAULT_VERIFY_MAX = 24; // 20
- static const int DEFAULT_ANGLE = 60; // 30
- static const int DEFAULT_DEBUG = 1;
- #define LOG_TAG "platelocate_native"
- #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
- #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
- extern "C"
- char* jstring2str(JNIEnv* env, jstring jstr) {
- char* rtn = NULL;
- jclass clsstring = env->FindClass("java/lang/String");
- jstring strencode = env->NewStringUTF("utf-8"); // "GB2312"
- jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
- jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
- jsize alen = env->GetArrayLength(barr);
- jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
- if (alen > 0) {
- rtn = (char *)malloc(alen + 1);
- memcpy(rtn, ba, alen);
- rtn[alen] = 0;
- }
- env->ReleaseByteArrayElements(barr, ba, 0);
- return rtn;
- }
- extern "C"
- jstring
- Java_com_example_gzh_myplatelocate_PlateRecognizer_stringFromJNI(
- JNIEnv *env,
- jobject /* this */) {
- std::string hello = "Hello from C++ NDK 11111111111111";
- LOGE("== Hello from C++ NDK 11111111111111");
- return env->NewStringUTF(hello.c_str());
- }
- extern "C"
- JNIEXPORT jlong JNICALL
- Java_com_example_gzh_myplatelocate_PlateRecognizer_initPR(
- JNIEnv *env,
- jobject) {
- // const string *svm = (*env)->GetStringUTFChars(env, svmpath, 0);
- // const string *ann = (*env)->GetStringUTFChars(env, annpath, 0);
- CPlateLocate *pr = new CPlateLocate();
- return (jlong)pr;
- }
- extern "C"
- JNIEXPORT jlong JNICALL
- Java_com_example_gzh_myplatelocate_PlateRecognizer_uninitPR(
- JNIEnv *env,
- jobject,
- jlong recognizerPtr
- )
- {
- LOGE("== Java_com_example_gzh_myplatelocate_PlateRecognizer_uninitPR");
- CPlateLocate *pr = (CPlateLocate *)recognizerPtr;
- delete pr;
- return 0;
- }
- #if 0
- extern "C"
- JNIEXPORT void JNICALL
- Java_com_example_gzh_myplatelocate_PlateRecognizer_mySobelOper
- (JNIEnv * jenv,
- jlong thiz,
- jlong recognizerPtr,
- jlong imageGray, jlong faces)
- {
- Mat imgData_out;
- Mat& mGr = *(Mat*)imageGray;
- Mat& mRgb = *(Mat*)faces;
- LOGE("=1= Java_com_example_gzh_myplatelocate_PlateRecognizer_mySobelOper");
- LOGE("=2= mGr.cols=%d", mGr.cols);
- LOGE("=2= mGr.rows=%d", mGr.rows);
- LOGE("=2= mGr.dims=%d", mGr.dims);
- LOGE("=2= mGr.channels=%d", mGr.channels());
- // cv:cvtColor(mGr, mRgb, CV_RGB2GRAY);
- //mRgb = mRgb /255.0;
- CPlateLocate *pr = (CPlateLocate *)recognizerPtr;
- #if 1
- pr->sobelOper(mGr, imgData_out, m_GaussianBlurSize, m_MorphSizeWidth,m_MorphSizeHeight);
- #else
- #if 1
- pr->cvtgray(mGr, mRgb, CV_RGB2GRAY);
- #else
- cv:cvtColor(mGr, mRgb, CV_RGB2GRAY);
- #endif
- #endif
- LOGE("=2= imgData_out.cols=%d", imgData_out.cols);
- LOGE("=2= imgData_out.rows=%d", imgData_out.rows);
- imgData_out.dims = 0;
- LOGE("=2= imgData_out.dims=%d", imgData_out.dims);
- LOGE("=2= imgData_out.channels=%d", imgData_out.channels());
- // imgData_out = imgData_out / 255.0;
- // imgData_out.copyTo(*hist);
- LOGE("=3= imgData_outJava_com_example_gzh_myplatelocate_PlateRecognizer_mySobelOper");
- }
- #else
- extern "C"
- JNIEXPORT void JNICALL
- Java_com_example_gzh_myplatelocate_PlateRecognizer_mySobelOper
- (JNIEnv * jenv,
- jlong thiz,
- jlong recognizerPtr,
- jlong imageGray, jlong faces)
- {
- Mat imgData;
- Mat imgData_out;
- Mat *hist = new Mat();
- Mat& mGr = *(Mat*)imageGray;
- Mat& mRgb = *(Mat*)faces;
- // hist = &imgData_out;
- LOGE("=1= Java_com_example_gzh_myplatelocate_PlateRecognizer_mySobelOper");
- LOGE("=2= mGr.cols=%d", mGr.cols);
- LOGE("=2= mGr.rows=%d", mGr.rows);
- LOGE("=2= mGr.dims=%d", mGr.dims);
- LOGE("=2= mGr.channels=%d", mGr.channels());
- // cv:cvtColor(mGr, mRgb, CV_RGB2GRAY);
- //mRgb = mRgb /255.0;
- // CPlateLocate *pr = (CPlateLocate *)recognizerPtr;
- // pr->sobelOper(mGr, imgData_out, m_GaussianBlurSize, m_MorphSizeWidth,m_MorphSizeHeight);
- Mat mat_blur;
- LOGE("=1= sobelOper");
- mat_blur = mGr.clone();
- GaussianBlur(mGr, mat_blur, Size(m_GaussianBlurSize, m_GaussianBlurSize), 0, 0, BORDER_DEFAULT);
- LOGE("=2= sobelOper mat_blur.channels()=%d", mat_blur.channels());
- Mat mat_gray;
- if (mat_blur.channels() == 3 || mat_blur.channels() == 4)
- cvtColor(mat_blur, mat_gray, CV_RGB2GRAY);
- else if(mat_blur.channels() == 42)
- {
- mat_blur.convertTo(mat_gray, SOBEL_DDEPTH);
- }
- else
- mat_gray = mat_blur;
- LOGE("=3= sobelOper");
- int scale = SOBEL_SCALE;
- int delta = SOBEL_DELTA;
- int ddepth = SOBEL_DDEPTH;
- Mat grad_x, grad_y;
- Mat abs_grad_x, abs_grad_y;
- LOGE("=444= sobelOper");
- #if 1
- Sobel(mat_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);
- convertScaleAbs(grad_x, abs_grad_x);
- LOGE("=5= sobelOper");
- Mat grad;
- addWeighted(abs_grad_x, SOBEL_X_WEIGHT, 0, 0, 0, grad);
- Mat mat_threshold;
- double otsu_thresh_val = threshold(grad, mat_threshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
- LOGE("=6= sobelOper");
- Mat element = getStructuringElement(MORPH_RECT, Size(m_MorphSizeWidth, m_MorphSizeHeight));
- morphologyEx(mat_threshold, mat_threshold, MORPH_CLOSE, element);
- mRgb = mat_threshold;
- #else
- mRgb = mat_gray;
- #endif
- LOGE("=71= sobelOper");
- // faces = (jlong)hist;
- LOGE("=3= imgData_outJava_com_example_gzh_myplatelocate_PlateRecognizer_mySobelOper");
- }
- #endif
- extern "C"
- JNIEXPORT void JNICALL
- Java_com_example_gzh_myplatelocate_PlateRecognizer_myCvtColor
- (JNIEnv * jenv,
- jlong thiz,
- jlong imageGray, jlong faces)
- {
- Mat imgData;
- Mat imgData_out;
- Mat *hist = new Mat();
- imgData = *((Mat*)imageGray);
- Mat& mGr = *(Mat*)imageGray;
- Mat& mRgb = *(Mat*)faces;
- LOGE("== Java_com_example_gzh_myplatelocate_PlateRecognizer_myCvtColor");
- LOGE("=myCvtColor= mGr.channels=%d", mGr.channels());
- cv:cvtColor(mGr, mRgb, CV_RGB2GRAY);
- // mRgb = mRgb /255.0;
- LOGE("== Java_com_example_gzh_myplatelocate_PlateRecognizer_myCvtColor");
- }
- extern "C"
- JNIEXPORT jintArray JNICALL
- Java_com_example_gzh_myplatelocate_PlateRecognizer_getGrayImage(
- JNIEnv *env,
- jobject /* this */,
- jintArray pixels_,
- jint w,
- jint h
- ) {
- jint *pixels = env->GetIntArrayElements(pixels_, NULL);
- // TODO
- if(pixels==NULL){
- return NULL;
- }
- cv::Mat imgData(h, w, CV_8UC4, pixels);
- uchar *ptr = imgData.ptr(0);
- for (int i = 0; i < w * h; i++) {
- int grayScale = (int) (ptr[4 * i + 2] * 0.299 + ptr[4 * i + 1] * 0.587
- + ptr[4 * i + 0] * 0.114);
- ptr[4 * i + 1] = (uchar) grayScale;
- ptr[4 * i + 2] = (uchar) grayScale;
- ptr[4 * i + 0] = (uchar) grayScale;
- }
- int size = w * h;
- jintArray result = env->NewIntArray(size);
- env->SetIntArrayRegion(result, 0, size, pixels);
- env->ReleaseIntArrayElements(pixels_, pixels, 0);
- return result;
- }
复制代码
运行结果如下图:
附件是ubuntu系统的高斯模糊实现。
DragonCat liked
回复引用
Working