openCV操作像素的方式

前言

  • openCV操作像素的方式有十几种,但常用的也就三种,今天就讲解一下三种方式.

1.使用指针(像素数组): 优点是速度快耗时少
2.迭代器 : 优点是不会越界,安全性高
3.动态地址计算 : 优点是理解方式和现实逻辑一样,易于理解

今天通过一个改变图片灰度值的例子,讲解下操作像素的方式
我们知道,java 中图片是ARGB格式表示,但在OpenCV中,图片是以BGRA格式标识,所以我们在使用时需要进行变换.

将ARGB转换为BGRA
Mat img(h, w, CV_8UC4, (unsigned char *) arr);

灰度图 以数组存储每个像素的数据,每个数据叫做一个灰度值
将三个色值都改为 R*0.299+G*0.587+B*0.114 即 彩色转黑白公式

Vec   4        b
向量  4通道   数据类型(b代表uchar)
  • 下面是布局文件
      
  • 下面是主界面
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    static {
        System.loadLibrary("native-lib");
    }

    private Button btn_change_gray;
    private Bitmap bitmap;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       btn_change_gray = (Button) findViewById(R.id.btn_change_gray);
       btn_change_gray.setOnClickListener(this);
       bitmap = BitmapFactory.decodeResource(getResources(),   R.drawable.ds);
       iv.setImageBitmap(bitmap);
    }

     //改变图片灰度值
    public native int[] change_gray(int[] arr, int w, int h);

    @Override
    public void onClick(View v) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        switch (v.getId()) {
            case R.id.btn_change_gray:

                int[] p = new int[w * h];
                bitmap.getPixels(p, 0, w, 0, 0, w, h);
                //调用native方法进行图片处理
                int[] result_gray = change_gray(p, w, h);
                Bitmap bitmap1 = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
                bitmap1.setPixels(result_gray,0,w,0,0,w,h);
                iv.setImageBitmap(bitmap1);

                break;
      }
    }
}
  • 下面是cpp文件
    #include 
    #include 
    #include 
    #include 

    using namespace cv;
    using namespace std;

    extern "C"
    JNIEXPORT jintArray JNICALL
    Java_com_otitan_opencvdemo_MainActivity_change_1gray(JNIEnv *env, jobject jobj, jintArray arr_,
                                                     jint w, jint h) {
    jint *arr = env->GetIntArrayElements(arr_, NULL);
    if (arr == NULL) {
        return 0;
    }

    //将ARGB转换为BGRA
    Mat img(h, w, CV_8UC4, (unsigned char *) arr);



    //----------------------------------------------------------------------------
    //第一种:指针的方式操作像素
    //图片起始位置
     uchar *ptr = img.ptr(0);
     for (int i = 0; i < w * h; i++) {
         //R*0.299+G*0.587+B*0.114
         uchar GrayPixer = (uchar)(ptr[4 * i + 2] * 0.299 + ptr[4 *i + 1] * 0.587 + ptr[4 *i + 0] * 0.114);

         ptr[4 * i + 0] = GrayPixer;
         ptr[4 * i + 1] = GrayPixer;
         ptr[4 * i + 2] = GrayPixer;
     }
    //----------------------------------------------------------------------------


     //----------------------------------------------------------------------------
     //第二种:迭代器方式
     Mat_::iterator it = img.begin();
     Mat_::iterator itend = img.end();

     while (it != itend) {
         uchar temp = (*it)[2] * 0.299 + (*it)[1] * 0.587 + (*it)[0] * 0.114;
         (*it)[2] = temp;
         (*it)[1] = temp;
         (*it)[0] = temp;
         it++;
     }
    //----------------------------------------------------------------------------


    //----------------------------------------------------------------------------
    //第三种:动态地址计算
    int a = img.rows;//行
    int b = img.cols;//列

    for (int i = 0; i < a; ++i) {
        for (int j = 0; j < b; ++j) {
            uchar temp = img.at(i, j)[2] * 0.229 +
                         img.at(i, j)[1] * 0.587 +
                         img.at(i, j)[0] * 0.114;

            img.at(i, j)[2] = temp;
            img.at(i, j)[1] = temp;
            img.at(i, j)[0] = temp;
        }
    }

    //----------------------------------------------------------------------------

    int size = w * h;
    jintArray resultArray = env->NewIntArray(size);
    env->SetIntArrayRegion(resultArray, 0, size, arr);
    env->ReleaseIntArrayElements(arr_, arr, 0);
    return resultArray;
    }
  • 图片处理结果
处理前
openCV操作像素的方式_第1张图片
处理后

你可能感兴趣的:(openCV操作像素的方式)