图像增强算法的安卓移植

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

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

1. PC 端实现代码

#include <opencv2/opencv.hpp>

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;
}

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 <opencv2/opencv.hpp>

#include <string>
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

//image_enhancement.cpp

#include <opencv2/opencv.hpp>
#include <string>

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;
}

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;
}

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

protected native String enhancement(String imagePath);

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

2. 编译提示

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

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

三、存在问题

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

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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值