美文网首页
openCV操作像素的方式

openCV操作像素的方式

作者: 犀利的小眼神 | 来源:发表于2017-12-21 16:51 被阅读47次

前言

  • 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)
  • 下面是布局文件
      <Button
            android:id="@+id/btn_change_gray"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="灰度变换"/>
        
      <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
  • 下面是主界面
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 <jni.h>
    #include <string>
    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>

    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_<Vec4b>::iterator it = img.begin<Vec4b>();
     Mat_<Vec4b>::iterator itend = img.end<Vec4b>();

     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<Vec4b>(i, j)[2] * 0.229 +
                         img.at<Vec4b>(i, j)[1] * 0.587 +
                         img.at<Vec4b>(i, j)[0] * 0.114;

            img.at<Vec4b>(i, j)[2] = temp;
            img.at<Vec4b>(i, j)[1] = temp;
            img.at<Vec4b>(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操作像素的方式

    前言 openCV操作像素的方式有十几种,但常用的也就三种,今天就讲解一下三种方式. 1.使用指针(像素数组): ...

  • 004 图像像素的读写操作

    本节内容:图像像素操作:遍历与访问 C++ 在C++中访问OpenCV Mat对象每个像素点的像素值有两种方式: ...

  • Opencv操作像素示例

    下面的代码对图像中的B分量进行了增强 原始图像: 增强后的图像:

  • OpenCV(C++)操作像素总结

    OpenCV中提供了许多操作图像的函数,但是有时候我们需要直接操作像素来实现我们的功能,这篇文章总结了OpenCV...

  • OpenCV Python 系列教程3 - Core 组件

    基本知识 灰度图像的存储方式:image 多通道图像存储方式image OpenCV 中的通道存储为 BGR 像素...

  • openCV 改变图像的对比度和亮度

    原理: 在opencv改变图像的对比度和亮度本质是对像素点的操作,一个像素映射到另一个像素,用数学表示就是f(x,...

  • opencv库函数

    1,像素操作 2,opencv数据结构 CV_8U 0 8 16 24CV_8S 1 9 ...

  • 7.2 方框滤波

    OpenCV还提供了方框滤波方式,与均值滤波的不同在于,方框滤波不会计算像素均值,在均值滤波中,滤波结果的像素值是...

  • OpenCV2 像素基本操作

    先上代码。。。 1.读图片 第二个参数是类型 2.Mat_类型和Mat很像,在初始的时候指定了矩阵的元素的类型。M...

  • OpenCV for iOS 学习笔记(五)—— 使用OpenC

    环境配置 :OpenCV在xCode中的安装与环境配置环境配置 先上效果图 实现原理 通过对图像像素操作 : 线性...

网友评论

      本文标题:openCV操作像素的方式

      本文链接:https://www.haomeiwen.com/subject/dbpawxtx.html