图像处理一百题 Q.13. MAX-MINフィルタ(MAX-MIN 滤波)

题目

MAX-MINフィルタ(3x3)を実装せよ。

MAX-MINフィルタとはフィルタ内の画素の最大値と最小値の差を出力するフィルタであり、エッジ検出のフィルタの一つである。 エッジ検出とは画像内の線を検出るすることであり、このような画像内の情報を抜き出す操作を特徴抽出と呼ぶ。 エッジ検出では多くの場合、グレースケール画像に対してフィルタリングを行う。

实现一个 MAX-MIN 滤波器(3x3)。

MAX-MIN 滤波器是输出滤波器中像素的最大值和最小值之间的差的滤波器,并且是边缘检测滤波器之一。 边缘检测是为了检测图像中的线条,这种将图像中的信息提取出来的操作称为特征提取。 在许多情况下,边缘检测会在灰度图像上执行过滤。

代码

第一次写完,翻车了,不过还挺好看的,有一种彩画的质感:

out.jpg


#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <math.h>

cv::Mat Gaussian(cv::Mat in)
{
  cv::Mat out = cv::Mat::zeros(in.rows, in.cols, CV_8UC3);
  for (int x = 0; x < in.cols; x += 1)
    for (int y = 0; y < in.rows; y += 1)
    {
      for (int c = 0; c < in.channels(); c++)
      {

        uchar max = 0;
        uchar min = 0;
        for (int i = -1; i <= 1; i++)
        {
          for (int j = -1; j <= 1; j++)
          {
            int p_x = x + i;
            int p_y = y + j;
            if (!(p_x < 0 || p_y < 0 || p_x >= in.cols || p_y >= in.rows))
            {
              if (in.at<cv::Vec3b>(p_x, p_y)[c] > max)
              {
                max = in.at<cv::Vec3b>(p_x, p_y)[c];
              }
              if (in.at<cv::Vec3b>(p_x, p_y)[c] < min)
                min = in.at<cv::Vec3b>(p_x, p_y)[c] ;
            }
          }
        }
        out.at<cv::Vec3b>(x, y)[c] = max - min;
      }
    }

  return out;
}

int main(int argc, const char *argv[])
{
  cv::Mat img = cv::imread("imori.jpg", cv::IMREAD_COLOR);
  cv::Mat out = Gaussian(img);
  cv::imwrite("out.jpg", out);
  cv::imshow("sample", out);
  cv::waitKey(0);
  cv::destroyAllWindows();
  return 0;
}

记得加上编译参数 -lopencv_imgproc

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>
#include <math.h>

cv::Mat MaxMin(cv::Mat in)
{

  cv::Mat out = cv::Mat::zeros(in.rows, in.cols, CV_8UC1);
  for (int x = 0; x < in.cols; x += 1)
    for (int y = 0; y < in.rows; y += 1)
    {
        double max = 0;
        double min = (uchar)256;
        for (int i = -1; i <= 1; i++)
        {
          for (int j = -1; j <= 1; j++)
          {
            int p_x = x + i;
            int p_y = y + j;
            if (!(p_x < 0 || p_y < 0 || p_x >= in.cols || p_y >= in.rows))
            {
              if (in.at<uchar>(p_x, p_y) > max)
              {
                max = in.at<uchar>(p_x, p_y);
              }
              if (in.at<uchar>(p_x, p_y) < min)
                {
                  min = in.at<uchar>(p_x, p_y) ;
                }
            }
          }
        out.at<uchar>(x, y) = (uchar)(max - min);
      }
    }

  return out;
}

int main(int argc, const char *argv[])
{
  cv::Mat img = cv::imread("imori.jpg", cv::IMREAD_COLOR);
  cv::Mat cvt = cv::Mat::zeros(img.rows, img.cols, CV_8UC1);
  cv::cvtColor(img,cvt,cv::COLOR_RGB2GRAY);
  cv::Mat out = MaxMin(cvt);
  cv::imwrite("out.jpg", out);
  cv::imshow("sample", out);
  cv::waitKey(0);
  cv::destroyAllWindows();
  return 0;
}

似乎还是不对啊。

一个来自凌晨的更新:终于搞定了。


#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>
#include <math.h>

cv::Mat MaxMin(cv::Mat in)
{

  cv::Mat out = cv::Mat::zeros(in.rows, in.cols, CV_8UC1);
  for (int x = 0; x < in.cols; x += 1)
    for (int y = 0; y < in.rows; y += 1)
    {
        double max = 0;
        double min = 256;
        for (int i = -1; i <= 1; i++)
        {
          for (int j = -1; j <= 1; j++)
          {
            int p_x = x + i;
            int p_y = y + j;
            if (!(p_x < 0 || p_y < 0 || p_x >= in.cols || p_y >= in.rows))
            {
              if (in.at<uchar>(p_x, p_y) > max)
              {
                max = in.at<uchar>(p_x, p_y);
              }
              if (in.at<uchar>(p_x, p_y) < min)
                {
                  min = in.at<uchar>(p_x, p_y) ;
                }
            }
          }
        out.at<uchar>(x, y) = (uchar)(max - min);
      }
    }

  return out;
}

int main(int argc, const char *argv[])
{
  cv::Mat img = cv::imread("imori.jpg", cv::IMREAD_COLOR);
  cv::Mat cvt = cv::Mat::zeros(img.rows, img.cols, CV_8UC1);
  cv::cvtColor(img,cvt,cv::COLOR_RGB2GRAY);
  cv::Mat out = MaxMin(cvt);
  cv::imwrite("out.jpg", out);
  cv::imshow("sample", out);
  cv::waitKey(0);
  cv::destroyAllWindows();
  return 0

这个算法是我见过的比较神奇的,太有趣了!

发表留言

本站启用了垃圾评论检测插件,如果误删请联系我~