2018-08-14 10:10:17 qq_26907755 阅读数 403
  • C++编程FFMpeg(QT5+OpenCV)实战--实时美颜直播推流

    C++编程FFMpeg实时美颜直播推流实战视频培训教程,本课程基于ffmpeg,qt5,opencv进行实战教学。 基于c++编程,掌握录制视频(rtsp和系统相机)录制音频(qt)开发方法,掌握音视频各类参数含义,掌握音视频编码(h264+acc),磨皮美颜(opencv),音视频封装(flv),基于rtmp协议推流。多线程处理技术。掌握nginx-rtmp和crtmpserver的直播服务器配置。

    15282 人正在学习 去看看 夏曹俊

图片的读取,通过函数cv::imread()来实现的;显示通过函数cv::imshow()来实现;而保存则通过cv::imwrite()来实现

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include<opencv2/face.hpp>
#include<iostream>
#include<math.h>
#include <string> 
#include<fstream> 
using namespace cv::face;
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;

int main()
{
    /*
    IMREAD_UNCHANGED (<0) 表示加载原图,不做任何改变
    IMREAD_GRAYSCALE ( 0)表示把原图作为灰度图像加载进来
    IMREAD_COLOR (>0) 表示把原图作为RGB图像加载进来,默认 3通道没有 alpha
    */
    Mat src = imread("C:/Users/Administrator/Desktop/pic/5.jpg", IMREAD_COLOR);//可以不写第二个参数,默认原图
    /*读取图片,OpenCV支持:
    Windows位图-.bmp, *.dib
    JPEG文件 - *.jpeg, *.jpg, *.jpe
    PNG图片 - *.png
    便携文件格式- *.pbm, *.pgm, *.ppm
    Sun rasters光栅文件 - *.sr, *.ras
    TIFF 文件 - *.tiff, *.tif
    */
    if (src.empty())
    {
        cout << ("could not load image...") << endl;

    }
    namedWindow("input", CV_WINDOW_AUTOSIZE);//创建窗口,自动大小,可以省略这一步
    imshow("input", src);//显示图片,这个也会创建一个窗口,如果这个winname与上面窗口的winname不一致,会导致有两个窗口

     //第二个窗口显示转换了颜色空间的图片
    //namedWindow("output", CV_WINDOW_AUTOSIZE);
    Mat output;
    //cvtColor(src, output, CV_BGR2GRAY);//RGB图像转换成灰度图,实际上,三通道RGB的图像的顺序是 BGR,所以 CV_BGR2GRAY 是BGR开头
    //cvtColor(src, output, CV_BGR2HLS);//RGB图像转换成HLS颜色空间(专调亮度?),色相(H)、亮度(L)、饱和度(S)。 OpenCV提供转换的颜色空间还有其他很多,待研究..
    cvtColor(src, output, CV_BGR2HSV);//RGB图像转换成HSV颜色空间(专调饱和度?),色调(色相)(H),饱和度(S),明度(亮度)(V)
    imshow("output", output);//显示第二个图片
                                     //保存图片
    imwrite("C:/Users/Administrator/Desktop/pic/w5.jpg", output);//保存的图片的格式由给的字符串决定,给png就是png,jpg就是jpg,tif就是tif,write的结果:png比jpg大,tif几乎是原图大小
    waitKey(0);//一检查到键盘活动就关闭,参数delay如果传0表示阻塞等待键盘事件,传大于0表示只阻塞等待多少毫秒,键盘无响应返回-1
}

结果:
这里写图片描述

2019-11-03 20:05:25 qq_40515692 阅读数 315
  • C++编程FFMpeg(QT5+OpenCV)实战--实时美颜直播推流

    C++编程FFMpeg实时美颜直播推流实战视频培训教程,本课程基于ffmpeg,qt5,opencv进行实战教学。 基于c++编程,掌握录制视频(rtsp和系统相机)录制音频(qt)开发方法,掌握音视频各类参数含义,掌握音视频编码(h264+acc),磨皮美颜(opencv),音视频封装(flv),基于rtmp协议推流。多线程处理技术。掌握nginx-rtmp和crtmpserver的直播服务器配置。

    15282 人正在学习 去看看 夏曹俊

OpenCv介绍

  • OpenCv是什么呢?

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了很多函数,这些函数非常高效地实现了计算机视觉算法(最基本的滤波到高级的物体检测皆有涵盖)。

  • OpenCv支持什么语言呢?

OpenCV 使用 C/C++ 开发,同时也提供了 Python、Java、MATLAB 等其他语言的接口。而这个专栏将只使用C++开发,一个重要的原因是自己更习惯C++的编程方式。而用C++也符合对高性能的追求。这也说明如果你要看这个专栏,则需要有一些C++基础。

  • C++需要什么地步才可以看呢?

第一就是需要明确的是,对于很酷的视觉算法,理解算法本身才是最重要的。
第二就是C++的基础越好,你越能写出简洁、高效的程序。
第三就是没错,还是需要C++基础,你逃避不了,但是,编程基础不需要太多,学习变量和数据类型、循环结构和选择结构、数组、函数、预处理命令、指针、结构体这些C语言基本的东西。了解类和对象、C++引用、模板、STL(标准模板库)就可以开始学习了(对于某些教材的各种多重继承和把脑袋都调晕的构造函数了解就行)。

如果你还没有这些基础,我推荐你去看视频或者看书,我非常不推荐抱着一本砖头书就一步一步看,疯狂的记笔记,而没有自己多写一些比如:计算器、简单的数据结构的代码。我比较推荐先看视频,如果你还是喜欢看书,那尽量选择一些评价高的书(选择评价高的书时,需要注意它适合初学者还是进阶的读者),以及尽量不要选择教材(有些教材考什么++i+=1;或者各种无脑指针已经偏离了程序应该简洁明确的本质了)。

  • 我需要配置什么东西吗?

OpenCV 是跨平台的,可以在 Windows、Linux、Mac OS、Android、iOS 等操作系统上运行。这个专栏,演示都是在Window10的Visual Studio(VS)上的。对于初学者我建议抛弃VC6.0++,安装VS,如果你是Linux用户,直接用CLion也可以配置好OpenCv后完美运行。安装好VS后,你需要网上安装OpenCv的安装包。

  • OpenCV下载和安装

https://opencv.org/releases.html 可以发现最新的为 Windows 准备的最新版本 OpenCV 下载链接(现在有OpenCv4了,你可以选择OpenCv3)。可以通过这个链接下载一个 EXE 文件,该文件会把预编译好的 OpenCV 解压到你的电脑上,预编译版本支持不同版本的 Visual Studio 环境。

你也可以通过源代码编译 OpenCV,进行安装,但是会麻烦不少。

文章目录

  • 这两篇文章主要讲的安装好OpenCv后如何进行环境配置,如果你配置出现任何问题,都欢迎您在文末评论留言,但是请尽量描述清楚,然后讲的OpenCv的一些基本例子。若有错误,欢迎您在文末评论留言。

OpenCv VS C++ 图像处理(一): 环境配置及简单使用

OpenCv VS C++ 图像处理(二):OpenCv基本用法

  • 这两篇直接给了图像识别相关的代码,粗略讲了角点、图像识别相关的知识,在OpenCv3上正常运行。若有错误,欢迎您在文末评论留言。

OpenCv3 VS C++ (三):图像识别

OpenCv3 VS C++ (四):图像识别

  • 这两篇是自己实现的超像素分割处理、Kmeans分类分割图片的相关代码,并较详细的进行了讲解,非常推荐大家自己试试。若有错误,欢迎您在文末评论留言。

OpenCv3 VS C++ (五):SLIC超像素分割算法

OpenCv3 VS C++ (六):Kmeans分类算法

持续更新中。。。

2019-06-11 20:32:32 qq_35975447 阅读数 101
  • C++编程FFMpeg(QT5+OpenCV)实战--实时美颜直播推流

    C++编程FFMpeg实时美颜直播推流实战视频培训教程,本课程基于ffmpeg,qt5,opencv进行实战教学。 基于c++编程,掌握录制视频(rtsp和系统相机)录制音频(qt)开发方法,掌握音视频各类参数含义,掌握音视频编码(h264+acc),磨皮美颜(opencv),音视频封装(flv),基于rtmp协议推流。多线程处理技术。掌握nginx-rtmp和crtmpserver的直播服务器配置。

    15282 人正在学习 去看看 夏曹俊
2018-10-28 23:02:40 Aidam_Bo 阅读数 580
  • C++编程FFMpeg(QT5+OpenCV)实战--实时美颜直播推流

    C++编程FFMpeg实时美颜直播推流实战视频培训教程,本课程基于ffmpeg,qt5,opencv进行实战教学。 基于c++编程,掌握录制视频(rtsp和系统相机)录制音频(qt)开发方法,掌握音视频各类参数含义,掌握音视频编码(h264+acc),磨皮美颜(opencv),音视频封装(flv),基于rtmp协议推流。多线程处理技术。掌握nginx-rtmp和crtmpserver的直播服务器配置。

    15282 人正在学习 去看看 夏曹俊


 

//添加椒盐噪声
void salt(Mat& src,int number)
{
    for (int i = 0; i < number; i++)
    {
        int r = static_cast<int>(rng.uniform(0, src.rows));
        int c = static_cast<int>(rng.uniform(0, src.cols));
        int k = (static_cast<int>(rng.uniform(0, 1000))&1);
        if(k==1)
            src.at<uchar>(r, c) = 255;
        else
            src.at<uchar>(r, c) = 0;
    }
    return;
}
/*
* @ drt :高斯方差
* @ Medium :高斯均值
*/
int Get_Gauss(int Medium, int drt)
{
    //产生高斯样本,以U为均值,D为均方差
    double sum = 0;
    for (int i = 0; i<12; i++) 
        sum += rand() / 32767.00;
    //计算机中rand()函数为-32767~+32767(2^15-1)
    //故sum+为0~1之间的均匀随机变量
    return int(Medium + drt*(sum - 6));
    //产生均值为U,标准差为D的高斯分布的样本,并返回
}
/*
* variance :高斯噪声的方差
*/


 

//添加高斯噪声
void ImgAddGaussNoise1( uchar * dstImgbuff, int srcwith, int srcheigh, int chanels)
{
    assert( srcwith > 0 && srcheigh > 0);
    int bytecount = srcwith * srcheigh * chanels;
 
    for (size_t i = 0; i < bytecount; i++)
    {
        int  iTemp = dstImgbuff[i] + Get_Gauss(0, 20);
        iTemp = iTemp > 255 ? 255 : iTemp;
        iTemp = iTemp < 0 ? 0 : iTemp;
        dstImgbuff[i] = iTemp;
    }
}


 

//均值求取
void Meanvalue(Mat* src, int indexrows, int indexcols, float* meanv, int ker)
{
    int lo = (ker - 1) / 2;
    float total = 0;
    for (int i = indexrows - lo; i <= indexrows + lo; i++)
    {
        for (int j = indexcols - lo; j <= indexcols + lo; j++)
        {
            total += src->at<uchar>(i, j);
        }
    }
    *meanv = total / (ker * ker);
    return;
}
//中值求取
void Media(Mat* src, int indexrows, int indexcols, int* meanv, int ker)
{
    int lo = (ker - 1) / 2;
    vector<int>moreo;
    for (int i = indexrows - lo; i <= indexrows + lo; i++)
    {
        for (int j = indexcols - lo; j <= indexcols + lo; j++)
        {
            moreo.push_back(src->at<uchar>(i, j));
        }
    }
    sort(moreo.begin(), moreo.end());
    *meanv = moreo.at(ker * ker / 2);
    return;
}


 

//局部方差求取
void Vvalue(Mat* src, int indexrows, int indexcols, int* vall, int ker, float mean)
{
    int lo = (ker - 1) / 2;
    float total = 0;
    for (int i = indexrows - lo; i <= indexrows + lo; i++)
    {
        for (int j = indexcols - lo; j <= indexcols + lo; j++)
        {
            total += pow((src->at<uchar>(i, j) - mean), 2);
        }
    }
    *vall = static_cast<int>(total);
    return;
}

 

//像素方差
void Variance(Mat& src, vector<test>& hierachy, int ker)
{
    int row = src.rows;
    int col = src.cols;
    int lo = (ker - 1) / 2;
    for (int ir = lo; ir < row - lo; ir++)
    {
        for (int jc = lo; jc < col - lo; jc++)
        {
            float means;
            int var;
            //计算均值
            Meanvalue(&src, ir, jc, &means, ker);
            Vvalue(&src, ir, jc, &var, ker, means);
            test temp;
            temp.menval = var;
            temp.x = ir;
            temp.y = jc;
            hierachy.push_back(temp);
        }
    }
    return;
}

 

//STL排序方式
bool SortByM1(const test &v1, const test &v2)//注意:本函数的参数的类型一定要与vector中元素的类型一致  
{
    return v1.menval < v2.menval;//升序排列  
}

 

//SSIM 结构相似比
Scalar getMSSIM(const Mat& i1, const Mat& i2)
{
    const double C1 = 6.5025, C2 = 58.5225;
    /***************************** INITS **********************************/
    int d = CV_32F;
 
    Mat I1, I2;
    i1.convertTo(I1, d);           // cannot calculate on one byte large values
    i2.convertTo(I2, d);
 
    int num = I1.channels();
    //cv::imshow("123", I1);
    //cv::waitKey();
 
    Mat I2_2 = I2.mul(I2);        // I2^2
    Mat I1_2 = I1.mul(I1);        // I1^2
    Mat I1_I2 = I1.mul(I2);        // I1 * I2
 
                                   /*************************** END INITS **********************************/
 
    Mat mu1, mu2;   // PRELIMINARY COMPUTING
    GaussianBlur(I1, mu1, Size(11, 11), 1.5);
    GaussianBlur(I2, mu2, Size(11, 11), 1.5);
 
    Mat mu1_2 = mu1.mul(mu1);
    Mat mu2_2 = mu2.mul(mu2);
    Mat mu1_mu2 = mu1.mul(mu2);
 
    Mat sigma1_2, sigma2_2, sigma12;
 
    GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);
    sigma1_2 -= mu1_2;
 
    GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);
    sigma2_2 -= mu2_2;
 
    GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);
    sigma12 -= mu1_mu2;
 
    ///////////////////////////////// FORMULA ////////////////////////////////
    Mat t1, t2, t3;
 
    t1 = 2 * mu1_mu2 + C1;
    t2 = 2 * sigma12 + C2;
    t3 = t1.mul(t2);              // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))
 
    t1 = mu1_2 + mu2_2 + C1;
    t2 = sigma1_2 + sigma2_2 + C2;
    t1 = t1.mul(t2);               // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))
 
    Mat ssim_map;
    divide(t3, t1, ssim_map);      // ssim_map =  t3./t1;
 
    Scalar mssim = mean(ssim_map); // mssim = average of ssim map
    return mssim;
}
//功能:局部均值求取 局部方差求取
/* zc 2018/07/08
parameters:
Mat*         src;         //待处理的图像
float*       meanv;       //保存局部均值
float*       dev;         //保存局部方差
int          indexrows;   //要求局部所在行
int          indexcols;   //要求局部所在列
int          ker;         //窗口大小系数
*/
void Meanvalue(Mat* src, float* meanv, float* dev, int indexrows, int indexcols,  int ker)
{
    int lo = (ker - 1) / 2;
    float total = 0;
    float total2 = 0;
    for (int i = indexrows - lo; i <= indexrows + lo; i++)
    {
        for (int j = indexcols - lo; j <= indexcols + lo; j++)
        {
            float temp = static_cast<float>(src->at<uchar>(i, j));
            total += temp;
            total2 += temp*temp;
        }
    }
    int size = ker * ker;
    *meanv = total / size;                                      //均值
    *dev = (total2 - (total*total) / size) / size;              //方差
    return;
}



 
 

2017-08-09 17:19:56 qq_27278957 阅读数 655
  • C++编程FFMpeg(QT5+OpenCV)实战--实时美颜直播推流

    C++编程FFMpeg实时美颜直播推流实战视频培训教程,本课程基于ffmpeg,qt5,opencv进行实战教学。 基于c++编程,掌握录制视频(rtsp和系统相机)录制音频(qt)开发方法,掌握音视频各类参数含义,掌握音视频编码(h264+acc),磨皮美颜(opencv),音视频封装(flv),基于rtmp协议推流。多线程处理技术。掌握nginx-rtmp和crtmpserver的直播服务器配置。

    15282 人正在学习 去看看 夏曹俊

         本文是参考博客名为“千里之外”的朋友的文章,感谢!原链接为:http://blog.csdn.net/pwh0996/article/details/8957764/   但是没有完全一样,做了一些修改,已实践可用。

        之前做的opencv图像处理,总是会依赖Opencv Manager,所以需要再安装一个Opencv Manager的apk,这样就比较不方便,很多人也不愿意。 所以今天用到的是纯C++,抛弃了Opencv Manager。

       首先上资源代码(注意:因为OpenCVSDK占内存超出我上传文件的限制额,所以我把它去除了,用的时候还需要下载opencv的sdk,放入jni目录中。怎么命名下面对jni目录介绍时会提到这点)点击下载

       下面是项目的步骤:

        1、首先在项目中创建一个jni目录。目录的文件列表如下图:

      下面将对这些文件一一介绍。

       1)ImageProc.cpp文件。C++文件,里面有图片处理的方法。

 

#include <ImageProc.h>
#include <opencv2/core/core.hpp>
#include <string>
#include <vector>

using namespace cv;
using namespace std;

void proc(Mat &src);

JNIEXPORT jintArray JNICALL Java_com_example_grayonlyc_ImageProc_grayProc
  (JNIEnv* env, jclass obj, jintArray buf, jint w, jint h, jfloatArray width, jfloatArray maskX, jfloatArray maskY){
    jint *cbuf;
    cbuf = env->GetIntArrayElements(buf, JNI_FALSE);
    if(cbuf == NULL){
        return 0;
    }

/////////////////  测试object数组      ///////////////
    jfloat *mx, *my;
    //jint length;
    mx = env->GetFloatArrayElements(maskX,JNI_FALSE);
    my = env->GetFloatArrayElements(maskY,JNI_FALSE);
    //length = env->GetArrayLength(maskX);

    Point2f mask[16];
    for(int i=0;i<16;i++){
    	mask[i].x = mx[i];
    	mask[i].y = my[i];
    }
    mask[0] = Point2f(0,1);
    mx[0] = mask[0].x;
    my[0] = mask[0].y;
    mx[1] = mask[1].x;
    my[1] = mask[1].y;
//////////////////////////////////////////////////

 /////////////////  测试float数组      ///////////////
    jfloat* arr;
    jint length;
    arr = env->GetFloatArrayElements(width,JNI_FALSE);
    length = env->GetArrayLength(width);

    float finWidth[15];
    for(int i=0;i<15;i++){
    	finWidth[i] = arr[i];
    }
    finWidth[0] = 0.1f;
    arr[0] = finWidth[0];
    //SetIntArrayRegion(width, 0, length, arr);
//////////////////////////////////////////////////

    Mat imgData(h, w, CV_8UC4, (unsigned char*)cbuf);

    proc(imgData);//C++处理

    int size=w * h;
    jintArray result = env->NewIntArray(size);
    env->SetIntArrayRegion(result, 0, size, cbuf);
    env->ReleaseIntArrayElements(buf, cbuf, 0);
    return result;
}

void proc(Mat &src){
	uchar* ptr = src.ptr(0);
	for(int i = 0; i < src.cols * src.rows; i ++){
    //计算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B
	        //对于一个int四字节,其彩色值存储方式为:BGRA
	    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] = grayScale;
	    ptr[4*i+2] = grayScale;
	    ptr[4*i+0] = grayScale;
	 }
}

         供Java调用的方法的命名规则为:Java_包名_类名_方法名。

 

        2)ImageProc.h头文件。声明定义C文件中用到的方法。声明规则也是:Java_包名_类名_方法名。

 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_grayonlyc_ImageProc */

#ifndef _Included_com_example_grayonlyc_ImageProc
#define _Included_com_example_grayonlyc_ImageProc
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_grayonlyc_ImageProc
 * Method:    grayProc
 * Signature: ([III[F[F[F)[I
 */
JNIEXPORT jintArray JNICALL Java_com_example_grayonlyc_ImageProc_grayProc
  (JNIEnv *, jclass, jintArray, jint, jint, jfloatArray, jfloatArray, jfloatArray);

#ifdef __cplusplus
}
#endif
#endif

         .h头文件可以自己手动创建,然后声明方法,也可以通过命令自动生成。介绍一下自动生成:

 

          在Eclipse中写好java文件保存后,会自动生成class文件,在bin目录的classes目录下,有自己项目的包名,在相应java的包下就有相应class文件。在doc中进入到classes目录下,输入javah com.example.grayonlyc.ImageProc即可以生成.h头文件。这里的包名是我自己的,需要改成你自己的。

          生成的头文件,可以自己修改成自己想要的名称,比如我这用的名称为ImageProc.h。

         3)Android.mk文件。这个文件是向ndk系统描述代码的信息和需要生成文件的信息。

 

LOCAL_PATH := $(call my-dir)  
include $(CLEAR_VARS)  
include $(LOCAL_PATH)/OpenCVsdk/native/jni/OpenCV.mk  
LOCAL_SRC_FILES  := ImageProc.cpp  
LOCAL_MODULE     := image_proc  
include $(BUILD_SHARED_LIBRARY)

         4)Application.mk文件。这个文件是用来描述你的程序需要哪些模块。

 

 

APP_STL := gnustl_static  
APP_CPPFLAGS := -frtti -fexceptions  
APP_ABI := armeabi-v7a  
APP_PLATFORM := android-19

         5)OpencvSDK  这个是opencv的官方sdk。我把名称改成了OpenCVSDK。它的目录列表如下:

          项目中因为OpencvSDK占内存超出我上传文件的限制额,所以我把它去除了,用的时候还需要下载opencv的sdk,然后把名称改成OpenCVSDK放入jni目录中就可以使用了,引用已经在Android.mk文件中写好了。

 

        6)以上5步都完成后,需要将C文件编译成so库供java使用。首先电脑里要下载好ndk,然后配置好环境变量(没有的话百度一下,很简单,解压后配置一下环境变量就OK)。然后在doc系统中进入jni中的C文件所在目录,输入命令:ndk-build 或者 ndk-build.cmd   然后就等待编译成功,就可以发现lib下相应的文件夹内就有libimage_proc.so库了。

          2、java文件。共有两个java文件。MainActivity.java和ImageProc.java文件。

          1)MainActivity.java

 

package com.example.grayonlyc;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.Config;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{
	private Button btnProc;  
    private ImageView imageView;  
    private TextView textView;  
    private Bitmap bmp;  
    private float[] width = new float[15];//手指宽度
    //private Point[] mask = new Point[16];
    private float[] maskX = new float[16];//X坐标
    private float[] maskY = new float[16];//Y坐标

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
        System.loadLibrary("image_proc"); 
        
        btnProc = (Button) findViewById(R.id.btn_gray_process);  
        imageView = (ImageView) findViewById(R.id.image_view);  
        //textView = (TextView) findViewById(R.id.text_view);  
        //将lena图像加载程序中并进行显示  
        bmp = BitmapFactory.decodeResource(getResources(), R.drawable.lena);  
        imageView.setImageBitmap(bmp);  
        btnProc.setOnClickListener(this);
        
        for(int i=0;i<15;i++){       	
        	width[i] = 0.0f;
        	maskX[i] = 0;
        	maskY[i] = 0;		
        }
        maskX[15] = maskY[15] = 0;
        width[1] = 1.0f;
        maskX[1] = maskY[1] = 1;
        
        //textView.setText("width原值01:"+width[0]+";"+width[1]);
        //textView.setText("mask原值:("+ maskX[0] + "," + maskY[0] +") ; ("+ maskX[1] + "," + maskY[1] +")");
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		long current = System.currentTimeMillis();   
        int w = bmp.getWidth();  
        int h = bmp.getHeight();  
        int[] pixels = new int[w*h]; 
              
        
        bmp.getPixels(pixels, 0, w, 0, 0, w, h);  
        int[] resultInt = ImageProc.grayProc(pixels, w, h, width, maskX, maskY);  
        Bitmap resultImg = Bitmap.createBitmap(w, h, Config.ARGB_8888);  
        resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);  
        
        long performance = System.currentTimeMillis() - current;
        this.setTitle("NDK耗时"+ String.valueOf(performance) + " 毫秒");
        imageView.setImageBitmap(resultImg);    
        //textView.setText("mask改变值:("+ maskX[0] + "," + maskY[0] +") ; ("+ maskX[1] + "," + maskY[1] +")");
	}
}

          2)ImageProc.java  改文件中是声明了一个本地方法,调用C文件中相应的方法。命名规则:方法前要有native关键字,表示调用JNI中相应方法名的方法。

 

 

package com.example.grayonlyc;  

public class ImageProc {  
    public static native int[] grayProc(int[] pixels, int w, int h, float width[], float maskX[], float maskY[]);  
}

          3、布局文件,activity_main.xml  

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:orientation="vertical"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent" >  
      
    <Button   
        android:id="@+id/btn_gray_process"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:text="@string/str_proc"/>  
      
    <ImageView  
        android:id="@+id/image_view"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:contentDescription="@string/str_proc"/>  
         
</LinearLayout> 

           以上是这个工程所有的介绍,虽然是参考别人的,但是也是用心去了解和修改的,希望有所帮助。  

 

没有更多推荐了,返回首页