07_OpenCv图像掩膜操作

07_图像掩膜操作

一.以行为单位遍历Mat中的像素信息

  • 通过src.row(i,0,new byte[src.cols()*src.channels()])得到由图像第i行的像素信息组成的byte数组

  • 像素值的范围处理:保证运算后的像素值在0-255之间:

    private static int saturateCast(double pixelValue) {
        int newValue = (int) Math.round(pixelValue);
        if(newValue > 255) {
            newValue = 255;
        }
        if(newValue < 0) {
            newValue = 0;
        }
        return newValue;
    }
    

二.图像的掩膜操作

  • 图像的掩膜操作是指使用掩膜矩阵从上到下,从左到右对图像的每个像素进行卷积,卷积后的结果重新组成的新结果即为掩膜操作后的图像

  • 图像的矩阵表示(其中i从1~rows-1,j从1~cols-1,掩膜矩阵为3x3矩阵)
    src=[I(i1,j1)I(i1,j)I(i1,j+1)I(i,j1)I(i,j)I(i,j+1)I(i+1,j1)I(i+1,j)I(i+1,j+1)]src= \left[ \begin{matrix} I(i-1, j-1) &amp; I(i-1, j) &amp; I(i-1, j+1)\\ I(i, j-1) &amp; I(i, j) &amp; I(i, j+1)\\ I(i+1, j-1) &amp; I(i+1, j) &amp; I(i+1, j+1) \end{matrix} \right] src=⎣⎡​I(i−1,j−1)I(i,j−1)I(i+1,j−1)​I(i−1,j)I(i,j)I(i+1,j)​I(i−1,j+1)I(i,j+1)I(i+1,j+1)​⎦⎤​

  • 掩膜矩阵
    kernel=[0202102020]kernel= \left[ \begin{matrix} 0 &amp; -2 &amp; 0\\ -2 &amp; 10 &amp; -2\\ 0 &amp; -2 &amp; 0 \end{matrix} \right] kernel=⎣⎡​0−20​−210−2​0−20​⎦⎤​

  • 掩膜操作

    I(i,j) = 10*I(i,j) - [2*I(i-1, j) + 2*I(i+1, j) + 2*I(i, j-1) + 2*I(i, j+1)]
    
  • 通过掩膜操作可以提高图像对比度

三.通过调用Imgproc.filter2D方法实现图像掩膜操作

//1.将输入图像的Bitmap对象转换为Mat对象
Mat srcMat = new Mat();
Utils.bitmapToMat(src, srcMat);
//2.定义掩膜的Mat对象
Mat kernel = new Mat(new Size(3,3), CvType.CV_32S);
kernel.put(0, 0, new int[] {0,-2,0,-2,10,-2,0,-2,0});
//3.实现掩膜操作
Imgproc.filter2D(srcMat, srcMat, srcMat.depth(), kernel);
Utils.matToBitmap(srcMat, src);

四.通过遍历Mat对象实现图像掩膜操作

//1.将输入图像的Bitmap对象转换为Mat对象
Mat srcMat = new Mat();
Utils.bitmapToMat(src, srcMat);
//2.获取图像的宽度、高度和通道数
int width = srcMat.cols();
int height = srcMat.rows();
int channels = srcMat.channels();
//3.开辟缓冲取,存放一行的像素信息
byte[] preLine = new byte[width * channels];
byte[] currentLine = new byte[width * channels];
byte[] nextLine = new byte[width * channels];
byte[] outputLine = new byte[width * channels];

//3.以行为单位遍历Mat对象,并对每一行做像素运算
Mat dstMat = new Mat(srcMat.size(), srcMat.type());
for (int row = 1; row < height - 1; row++) {
    srcMat.get(row - 1, 0, preLine);
    srcMat.get(row, 0, currentLine);
    srcMat.get(row + 1, 0, nextLine);
    for (int col = channels; col < (width - 1) * channels; col++) {
        outputLine[col] = (byte) saturateCast(10 * (currentLine[col] & 0xff) - (2 * (preLine[col] & 0xff) + 2 * (nextLine[col] & 0xff) + 2 * (currentLine[col - channels] & 0xff) + 2 * (currentLine[col + channels] & 0xff)));
    }
    dstMat.put(row, 0, outputLine);
}

Utils.matToBitmap(dstMat, src);

五.运行结果

07_OpenCv图像掩膜操作

上一篇:ACM常见博弈(更新中)


下一篇:矩阵分解