openvc操作图片像素----之图像灰度处理

来源:互联网 发布:帝国cms 用户名不合法 编辑:程序博客网 时间:2024/06/05 05:39

灰度图 以数组存储每个像素的数据,每个数据叫做一个灰度值
彩色图像灰度处理公式:R*0.299+G*0.587+B*0.114
方式一:指针操作。

extern "C" {JNIEXPORT jintArray JNICALLJava_com_xy_opencv_ndk_1opencv002_MainActivity_grayPixels(JNIEnv *env, jclass type,                                                          jintArray pixels_, jint w, jint h) { jint *pixels = env->GetIntArrayElements(pixels_, NULL);    if (pixels == NULL) {        return 0;    }    //图片一进来时是ARGB  通过mat转换BGRA    Mat img(h, w, CV_8UC4, pixels);    //读取返回一个uchar数组    uchar* ptr = img.ptr(0);    //获取当前CPU的钟摆时间    double time0 = static_cast<double>(getTickCount());    /**     * 指针处理     */    //灰度处理图片    for(int i = 0; i < w * h; i++){        //R*0.299 + G * 0.587 + B * 0.114        uchar  grayPixel = (uchar)(ptr[4*i+2]*0.299+ptr[4*i+1]*0.587+ptr[4*i+0]*0.114);        ptr[4*i+0] = grayPixel;        ptr[4*i+1] = grayPixel;        ptr[4*i+2] = grayPixel;    }   //计算运行时间    time0 = ((double)getTickCount() - time0)/getTickFrequency();    __android_log_print(ANDROID_LOG_INFO,"JNI","%ld",time0);    int size = w * h;    jintArray result = env->NewIntArray(size);    env->SetIntArrayRegion(result, 0, size, pixels);    env->ReleaseIntArrayElements(pixels_,pixels,0);    env->ReleaseIntArrayElements(pixels_, pixels, 0);    return result;        }    }

方式二:迭代器处理。

extern "C" {JNIEXPORT jintArray JNICALLJava_com_xy_opencv_ndk_1opencv002_MainActivity_grayPixels(JNIEnv *env, jclass type,                                                          jintArray pixels_, jint w, jint h) { jint *pixels = env->GetIntArrayElements(pixels_, NULL);    if (pixels == NULL) {        return 0;    }    //图片一进来时是ARGB  通过mat转换BGRA    Mat img(h, w, CV_8UC4, pixels);       //获取当前CPU的钟摆时间    double time0 = static_cast<double>(getTickCount());    /**     * 迭代器处理     */    //起始位置的迭代器   // Vec3b是向量    Mat_<Vec3b>::iterator it = img.begin<Vec3b>();    //结束为止的迭代器    Mat_<Vec3b>::iterator itEnd = img.end<Vec3b>();    for (; it!= itEnd; ++it) {        uchar temp = (uchar)((*it)[2]*0.299+(*it)[1]*0.587+(*it)[0]*0.114);        (*it)[0] = temp;        (*it)[1] = temp;        (*it)[2] = temp;    }     //计算运行时间    time0 = ((double)getTickCount() - time0)/getTickFrequency();    __android_log_print(ANDROID_LOG_INFO,"JNI","%ld",time0);    int size = w * h;    jintArray result = env->NewIntArray(size);    env->SetIntArrayRegion(result, 0, size, pixels);    env->ReleaseIntArrayElements(pixels_,pixels,0);    env->ReleaseIntArrayElements(pixels_, pixels, 0);    return result;        }    }

方式三:动态地址计算。

extern "C" {JNIEXPORT jintArray JNICALLJava_com_xy_opencv_ndk_1opencv002_MainActivity_grayPixels(JNIEnv *env, jclass type,                                                          jintArray pixels_, jint w, jint h) { jint *pixels = env->GetIntArrayElements(pixels_, NULL);    if (pixels == NULL) {        return 0;    }    //图片一进来时是ARGB  通过mat转换BGRA    Mat img(h, w, CV_8UC4, pixels); /**     * 动态地址计算     * 得用Vec4b     */    int row = img.rows;    int col = img.cols;    for (int i = 0; i < row; i++) {        for (int j = 0; j < col; j++) {            uchar temp = (uchar)(img.at<Vec4b>(i,j)[2]*0.299                         +img.at<Vec4b>(i,j)[1]*0.587                         +img.at<Vec4b>(i,j)[0]*0.114);            img.at<Vec4b>(i,j)[0]=temp;            img.at<Vec4b>(i,j)[1]=temp;            img.at<Vec4b>(i,j)[2]=temp;        }    }    //计算运行时间    time0 = ((double)getTickCount() - time0)/getTickFrequency();    __android_log_print(ANDROID_LOG_INFO,"JNI","%ld",time0);    int size = w * h;    jintArray result = env->NewIntArray(size);    env->SetIntArrayRegion(result, 0, size, pixels);    env->ReleaseIntArrayElements(pixels_,pixels,0);    env->ReleaseIntArrayElements(pixels_, pixels, 0);    return result;        }    }

这三种方式中,性能最好的是第一种,耗时少,第二种和第三种耗时产不多,但第二种使用了迭代器,可以保证不会越界,安全性高,第三种方式使用了Mat中的方法去动态操作地址中的数据,便于理解。

原创粉丝点击