• 图像增强算法的安卓移植


    一、图像增强代码的 C++ 实现

    在博客 一种基于Opencv文档图像增强算法的实现 提到了一种基于 C++ OpenCV 的图像增强算法, 并添加了辅助增强算法使效果更加明显.

    1. PC 端实现代码

    #include 
    
    using namespace std;
    using namespace cv;
    
    //Gamma校正 fGamaa=0.45是常用值
    void GammaCorrection(Mat& src, Mat& dst, float fGamma)
    {
    	CV_Assert(src.data);
    	// accept only char type matrices
    	CV_Assert(src.depth() != sizeof(uchar));
    	// build look up table
    	unsigned char lut[256];
    	for (int i = 0; i < 256; i++)
    	{
    		lut[i] = saturate_cast<uchar>(pow((float)(i / 255.0), fGamma) * 255.0f);
    	}
    
    	dst = src.clone();
    	const int channels = dst.channels();
    	switch (channels)
    	{
    	case 1:
    	{
    
    		MatIterator_<uchar> it, end;
    		for (it = dst.begin<uchar>(), end = dst.end<uchar>(); it != end; it++)
    			*it = lut[(*it)];
    
    		break;
    	}
    	case 3:
    	{
    
    		MatIterator_<Vec3b> it, end;
    		for (it = dst.begin<Vec3b>(), end = dst.end<Vec3b>(); it != end; it++)
    		{
    			(*it)[0] = lut[((*it)[0])];
    			(*it)[1] = lut[((*it)[1])];
    			(*it)[2] = lut[((*it)[2])];
    		}
    		break;
    	}
    	}
    }
    
    int main(int argc, char** argv)
    {   
    	string addr = "C:\\Users\\64975\\Desktop\\test1.jpg";
    	Mat image = imread(addr);
    	//划分算法
    	//如果混合色与基色相同则结果色为白色
    	//如混合色为白色则结果色为基色不变
    	//如混合色为黑色则结果色为白色
    	Mat src = image.clone();
    	src.convertTo(src, CV_32FC3, 1.0 / 255);
    	Mat gauss;
    	Mat dst = src.clone();
    	GaussianBlur(src, gauss, Size(101, 101), 0);
    	dst = src / gauss;
    	dst.convertTo(dst, CV_8UC3, 255);
    	//gamma变换
    	Mat ss;
    	Mat matGamma;
    	ss = dst.clone();
    	GammaCorrection(ss, matGamma, 1.5);
    	imwrite("C:\\Users\\64975\\Desktop\\test1_out.jpg", matGamma);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    2. 图片处理前后对比

    上述图片中, 左侧为未处理图片, 右侧为处理后的图片.

    可以明显发现, 由于光线所造成的阴影部分以及背景颜色在处理后都可以忽略不计, 并且图片中的文字质量仍保证在可辨识的状态.

    3. 对处理前后图片的模型识别结果

    (注: 图片中文字过多使得检测模型只能检测到部分, 故测试采用文字数较少图片进行测试)

    效果不是很明显, 还需要更多的测试来对其图像增强效果进行判断. 为了简便步骤, 这步工作在移植该算法到安卓端后进行.

    二、图像增强算法移植安卓

    1. 移植过程

    Step 1 : 在 xxx/src/main/cpp 文件夹下新建两个文件 image_enhancement.cpp 和 image_enhancement.h

    Step 2 : 编写 image_enhancement.cpp 和 image_enhancement.h 文件, 这里为移植的代码.

    //image_enhancement.h
    
    #ifndef ANDROID_DEMO_IMAGE_ENHANCEMENT_H
    #define ANDROID_DEMO_IMAGE_ENHANCEMENT_H
    
    #include 
    
    #include 
    using namespace std;
    
    using namespace cv;
    void GammaCorrection(Mat &src,Mat &dst, float fGamma);
    std::string ImageEnhance(std::string addr);
    
    #endif //ANDROID_DEMO_IMAGE_ENHANCEMENT_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    //image_enhancement.cpp
    
    #include 
    #include 
    
    using namespace std;
    using namespace cv;
    void GammaCorrection(Mat& src, Mat& dst, float fGamma)
    {
        CV_Assert(src.data);
        // accept only char type matrices
        CV_Assert(src.depth() != sizeof(uchar));
        // build look up table
        unsigned char lut[256];
        for (int i = 0; i < 256; i++)
        {
            lut[i] = saturate_cast<uchar>(pow((float)(i / 255.0), fGamma) * 255.0f);
        }
    
        dst = src.clone();
        const int channels = dst.channels();
        switch (channels)
        {
            case 1:
            {
    
                MatIterator_<uchar> it, end;
                for (it = dst.begin<uchar>(), end = dst.end<uchar>(); it != end; it++)
                    *it = lut[(*it)];
    
                break;
            }
            case 3:
            {
    
                MatIterator_<Vec3b> it, end;
                for (it = dst.begin<Vec3b>(), end = dst.end<Vec3b>(); it != end; it++)
                {
                    (*it)[0] = lut[((*it)[0])];
                    (*it)[1] = lut[((*it)[1])];
                    (*it)[2] = lut[((*it)[2])];
                }
                break;
            }
        }
    }
    
    std::string ImageEnhance(std::string addr) {
        Mat image = imread(addr);
        Mat src = image.clone();
        src.convertTo(src, CV_32FC3, 1.0 / 255);
        Mat gauss;
        Mat dst = src.clone();
        GaussianBlur(src, gauss, Size(101, 101), 0);
        dst = src / gauss;
        dst.convertTo(dst, CV_8UC3, 255);
        //gamma变换
        Mat ss;
        Mat matGamma;
        ss = dst.clone();
        GammaCorrection(ss, matGamma, 1.5);
        return addr;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    Step 3 : 在 xxx/src/main/cpp/native.cpp 文件末尾添加函数

    为了满足 JNI 的要求, 这里的函数命名都需要严格要求

    extern "C" JNIEXPORT jstring JNICALL
    Java_com_baidu_paddle_lite_demo_ocr_OCRPredictorNative_enhancement(JNIEnv *env, jobject thiz,jstring image_path) {
        std::string image_path1 = jstring_to_cpp_string(env, image_path);
        std::string image_out_path1 = ImageEnhance(image_path1);
        jstring j_string = cpp_string_to_jstring(env, image_out_path1);
        return j_string;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Step 4 : 在 xxx/src/main/java/xxxxx/OCRPredictorNative.java 文件中添加函数, 作为 Java 调用 C++ 的接口.

    protected native String enhancement(String imagePath);
    
    • 1

    Step 5 : 根据需要调用函数处理图像.

    2. 编译提示

    观察编译结果可能会发现并没有生成有关 image_enhancement 的 .o 文件. 这时就会出现链接文件时找不到 ImageEnhance() 函数.

    需要删除 根目录/app/.cxx 和 根目录/app/build 两个文件夹之后再 Make Build 该项目.

    三、存在问题

    • 目前图像增强代码移植安卓失败, 会出现 Assertion failed locateROI 之类的错误. 暂时还没有解决办法.

    • 在初期测试时, 对于文字占比较大的图片虽然识别率不高, 但是能够全部检测到. 但是在最近测试时发现, 模型对于此类图片的检测率只能达到 50 % 甚至更少. 无论使用其他开源模型还是使用官方网页模型以及官方在 PC 上的模型测试都是如此.

  • 相关阅读:
    [运维|中间件] 东方通TongWeb使用笔记
    对于程序员什么最重要
    leetcode-1964:找出到每个位置为止最长的有效障碍赛跑路线
    oracle截取字符串前几位用substr函数如何操作?
    计算机网络复习-第五章传输层
    【Azure Event Hub】Event Hub的Process Data页面无法通过JSON格式预览数据
    【读书笔记】【Effective STL】算法
    【钉钉】通过钉钉机器人抓取群消息
    2023湖南中医药大学计算机考研信息汇总
    [LeetCode周赛复盘] 第 310 场周赛20220911
  • 原文地址:https://blog.csdn.net/qq_44309220/article/details/126892320