码迷,mamicode.com
首页 > 编程语言 > 详细

Python图像处理(4):滤波器

时间:2015-05-29 00:57:00      阅读:1137      评论:0      收藏:0      [点我收藏+]

标签:vs2013   python   图像处理   

快乐虾

http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651)

欢迎转载,但请保留作者信息


滤波器在图像处理中的应用非常广泛,OpenCV也有个直接使用滤波器掩码(核)的函数filter2D,将图像与核进行卷积运算得到目标图像。卷积是在每一个图像块与某个算子(核)之间进行的运算,而核就是一个固定大小的数值数组。


实际上,在OpenCV中很多算法都是用卷积实现的,包括一些边缘检测的算法。本文无意列举这些算法的原理,仅仅是考察一下OpenCV的实现,再尝试用Python调用这些算法,看看其效果。


采用的测试图像还是它:

技术分享


因为我们的最终目标是识别此图像中的杂草与棉花植株!


1.    FilterEngine


OpenCV中滤波的操作由FilterEngine这个类来完成,在源码的注释里清楚地说明了这个类的作用:


The Main Class for Image Filtering.

 The class can be used to apply an arbitrary filtering operation to an image.
 It contains all the necessary intermediate buffers, it computes extrapolated values
 of the "virtual" pixels outside of the image etc.
 Pointers to the initialized cv::FilterEngine instances
 are returned by various OpenCV functions, such as cv::createSeparableLinearFilter(),
 cv::createLinearFilter(), cv::createGaussianFilter(), cv::createDerivFilter(),
 cv::createBoxFilter() and cv::createMorphologyFilter().

 Using the class you can process large images by parts and build complex pipelines
 that include filtering as some of the stages. If all you need is to apply some pre-defined
 filtering operation, you may use cv::filter2D(), cv::erode(), cv::dilate() etc.
 functions that create FilterEngine internally.

下面是FilterEngine的一个典型使用方式:

void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
                      InputArray _kernelX, InputArray _kernelY, Point anchor,
                      double delta, int borderType )
{
    Mat src = _src.getMat(), kernelX = _kernelX.getMat(), kernelY = _kernelY.getMat();

    if( ddepth < 0 )
        ddepth = src.depth();

    _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
    Mat dst = _dst.getMat();

    Ptr<FilterEngine> f = createSeparableLinearFilter(src.type(),
        dst.type(), kernelX, kernelY, anchor, delta, borderType & ~BORDER_ISOLATED );
    f->apply(src, dst, Rect(0,0,-1,-1), Point(), (borderType & BORDER_ISOLATED) != 0 );
}

当然,如注释所说,我们几乎不需要直接使用这个类,但是了解它的用法对于我们理解和调试OpenCV是很有好处的。


2.    filter2D


下面试试直接给一个滤波器的矩阵看看效果。

# -*- coding: utf-8 -*- 
import cv2
import numpy as np

# filter2D

src = cv2.imread(‘f:\\tmp\\cotton.jpg‘)
cv2.imshow(‘src‘, src)

kernel = np.array([ [-1, -1, -1],
                    [-1,  8, -1],
                    [-1, -1, -1] ])

dst = cv2.filter2D(src, -1, kernel)
cv2.imshow(‘dst‘, dst)

cv2.waitKey()

结果就是这样的:

技术分享

3.    PythonC++


看看从Pythonfilter2DFilterEngine的执行过程。


首先是filter2Dwrapper函数:

static PyObject* pyopencv_filter2D(PyObject* , PyObject* args, PyObject* kw)
{
    PyObject* pyobj_src = NULL;
    Mat src;
    PyObject* pyobj_dst = NULL;
    Mat dst;
    int ddepth=0;
    PyObject* pyobj_kernel = NULL;
    Mat kernel;
    PyObject* pyobj_anchor = NULL;
    Point anchor=Point(-1,-1);
    double delta=0;
    int borderType=BORDER_DEFAULT;

    const char* keywords[] = { "src", "ddepth", "kernel", "dst", "anchor", "delta", "borderType", NULL };
    if( PyArg_ParseTupleAndKeywords(args, kw, "OiO|OOdi:filter2D", (char**)keywords, &pyobj_src, &ddepth, &pyobj_kernel, &pyobj_dst, &pyobj_anchor, &delta, &borderType) &&
        pyopencv_to(pyobj_src, src, ArgInfo("src", 0)) &&
        pyopencv_to(pyobj_dst, dst, ArgInfo("dst", 1)) &&
        pyopencv_to(pyobj_kernel, kernel, ArgInfo("kernel", 0)) &&
        pyopencv_to(pyobj_anchor, anchor, ArgInfo("anchor", 0)) )
    {
        ERRWRAP2( cv::filter2D(src, dst, ddepth, kernel, anchor, delta, borderType));
        return pyopencv_from(dst);
    }

    return NULL;
}

这个函数是swig自动生成的,简单地对filter2D这个C++函数进行了包装,处理了输入参数和返回值。接着看cv::filter2D的实现过程:

void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
                   InputArray _kernel, Point anchor,
                   double delta, int borderType )
{
    Mat src = _src.getMat(), kernel = _kernel.getMat();

.....

    Ptr<FilterEngine> f = createLinearFilter(src.type(), dst.type(), kernel,
                                             anchor, delta, borderType & ~BORDER_ISOLATED );
    f->apply(src, dst, Rect(0,0,-1,-1), Point(), (borderType & BORDER_ISOLATED) != 0 );
}

和前面提到的sepFilter2D函数非常的相似!


cv::filter2D也是OpenCV开放的一个C++接口。











??

Python图像处理(4):滤波器

标签:vs2013   python   图像处理   

原文地址:http://blog.csdn.net/lights_joy/article/details/46137939

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!