简介
本篇是对实现图片处理功能:【图像修补】实现的记录。
实现原理
主要使用opencv集成的函数inpaint来实现,首先点击进入该功能的时候,创建一份掩码图像,像素全部置为0;接着复制一
份处理图像到matRestoration。
在复原功能操作时候,更新用户在图像上滑动过的坐标到掩码上,接着将该掩码和matRestoration作为inpaint函数的输入,进行图像修复操作,
结果图像,更新到mat中。
在擦除功能操作时候,在掩码上减去用户图像上滑动过的坐标,接着同样将该掩码和原图像作为inpaint函数的输入,进行图像修复操作。
inpaint函数使用,具体可以参考资料:http://blog.csdn.net/u011630458/article/details/44117269
具体代码
1、初始化
JNIEXPORT void JNICALL Java_com_example_restoration_myRestorationJNI_restorationInit
(JNIEnv* env, jclass obj, jlong imageRestorationInit, jint value){
Mat mat = Mat(*((Mat*)imageRestorationInit));
int Width = mat.rows;
int Height = mat.cols;
matRestoration = Mat(mat.size(), CV_8UC3);
mat.copyTo(matRestoration);
matRestorationMask = Mat(mat.size(), CV_8UC1, cv::Scalar(0, 0, 0));
}
在这里创建一份掩码图片。
2、修复功能
JNIEXPORT void JNICALL Java_com_example_restoration_myRestorationJNI_restorationWork
(JNIEnv *env, jclass, jlong imageRestorationWork, jint value, jintArray arrXY,jint screenHeight, jint screenWidth){
Mat mat = Mat(*((Mat*)imageRestorationWork));
int Height = mat.rows;
int Width = mat.cols;
int newTouch_y, newTouch_x;
int rectWdith = rectSize * value * Height / screenHeight / 2;
int rectHeight = rectSize * value * Height / screenHeight / 2;
jsize len = env->GetArrayLength(arrXY);
jintArray ret = env->NewIntArray(len);
jint *body = env->GetIntArrayElements(arrXY, 0);
int i, j;
int tmpX, tmpY;
CvScalar s1;
for(i=1; i< len;){
if((body[i] == 0) && (body[i-1] == 0)){
break;
}
tmpX = body[i-1] / rectWdith;
tmpY = body[i] / rectHeight;
newTouch_y = Width * body[i] / screenWidth;
newTouch_x = Height * body[i-1] / screenHeight;
rectangle(matRestorationMask, cvPoint(newTouch_x - rectWdith, newTouch_y - rectHeight),
cvPoint(newTouch_x + rectWdith, newTouch_y + rectHeight),cvScalar(255,255,255), -1);
i += 2;
}
inpaint(matRestoration, matRestorationMask, mat, 1, CV_INPAINT_TELEA);
}
和之前的马赛克功能一样,传入的arrXY数组为当前用户在图片上滑动经过的所有坐标位置。接着根据这些坐标信息更新掩码图像matRestorationMask。最后传入到处理函数inpaint中。
3、清除功能。
JNIEXPORT void JNICALL Java_com_example_restoration_myRestorationJNI_restorationClear
(JNIEnv *env, jclass, jlong imageRestorationClear, jint value, jintArray arrXY,jint screenHeight, jint screenWidth){
Mat mat = Mat(*((Mat*)imageRestorationClear));
int Height = mat.rows;
int Width = mat.cols;
int newTouch_y, newTouch_x;
int rectWdith = rectSize * value * Height / screenHeight / 2;
int rectHeight = rectSize * value * Height / screenHeight / 2;
IplImage src1, src2, src3;
jsize len = env->GetArrayLength(arrXY);
jintArray ret = env->NewIntArray(len);
jint *body = env->GetIntArrayElements(arrXY, 0);
int i, j;
int tmpX, tmpY;
CvScalar s1;
for(i=1; i< len;){
if((body[i] == 0) && (body[i-1] == 0)){
break;
}
tmpX = body[i-1] / rectWdith;
tmpY = body[i] / rectHeight;
newTouch_y = Width * body[i] / screenWidth;
newTouch_x = Height * body[i-1] / screenHeight;
rectangle(matRestorationMask, cvPoint(newTouch_x - rectWdith, newTouch_y - rectHeight),
cvPoint(newTouch_x + rectWdith, newTouch_y + rectHeight),cvScalar(0, 0, 0), -1);
i += 2;
}
inpaint(matRestoration, matRestorationMask, mat, 1, CV_INPAINT_TELEA);
}
同样根据滑动轨迹坐标数组arrXY更新掩码图像matRestorationMask,然后根据掩码图像来选择从修复后图像matRestoration中,选择像素替换到处理图像mat中。
效果演示
对应的效果图片如下:
原图像 修复图像
具体演示下载:http://download.csdn.net/detail/u011630458/9261617