Winn et. al. use a standard set of filters for extracting features from images: Gaussian, derivatives of Gaussian (aka DoG), and Laplacian of Gaussian (aka LoG). Here's what they look like:

Gaussian | |

Laplacian of Gaussian | |

Y-derivative of Gaussian | |

X-derivative of Gaussian |

OpenCV has a method for computing GaussianBlur which is sufficiently flexible to reproduce Winn et. al., but to reproduce their usage of DoG and LoG I wrote my own OpenCV kernels (although maybe a combination of the GaussianBlur method with the Laplacian method and Sobel method would work?). It turns out separable filters are much faster and everything above except the LoG is separable; in addition the LoG can be written as the sum of two separable filters, the second derivative of Gaussian in x and y. Thus with something like

#include <string>

#include "cv.h"

#include "highgui.h"

#include "cyclopsutil.hh"

using namespace cv;

using namespace cyclops;

int main (int, char** argv)

{

string file (argv[1]);

Mat img = imread (file);

vector<Mat> color (3);

assert (! img.empty ());

assert (img.channels () == 3);

cvtColor (img, img, CV_BGR2Lab);

split (img, color);

imwrite (file + ".L.png", color[0]);

imwrite (file + ".a.png", color[1]);

imwrite (file + ".b.png", color[2]);

for (int sigma = 1; sigma < 16; sigma *= 2)

{

string labels[3] = { string ("L"), string ("a"), string ("b") };

Mat conv = color[0].clone ();

Mat convtwo = color[0].clone ();

std::stringstream out;

out << sigma;

GaussianBlur (color[0], conv, Size (6 * sigma + 1, 6 * sigma + 1), sigma, sigma, BORDER_REPLICATE);

imwrite (file + "." + labels[0] + ".gauss." + out.str () + ".png", conv);

sepFilter2D (color[0], conv, -1, dygauss_kernelx (sigma), dygauss_kernely (sigma), Point (-1, -1), 0, BORDER_REPLICATE);

imwrite (file + "." + labels[0] + ".dygauss." + out.str () + ".png", conv);

sepFilter2D (color[0], conv, -1, dxgauss_kernelx (sigma), dxgauss_kernely (sigma), Point (-1, -1), 0, BORDER_REPLICATE);

imwrite (file + "." + labels[0] + ".dxgauss." + out.str () + ".png", conv);

sepFilter2D (color[0], conv, -1, dyygauss_kernelx (sigma), dyygauss_kernely (sigma), Point (-1, -1), 0, BORDER_REPLICATE);

imwrite (file + "." + labels[0] + ".dyygauss." + out.str () + ".png", conv);

sepFilter2D (color[0], convtwo, -1, dxxgauss_kernelx (sigma), dxxgauss_kernely (sigma), Point (-1, -1), 0, BORDER_REPLICATE);

imwrite (file + "." + labels[0] + ".dxxgauss." + out.str () + ".png", convtwo);

imwrite (file + "." + labels[0] + ".lapgauss." + out.str () + ".png", conv + convtwo);

}

return 0;

}

applied to our awesome cop car picture's luminosity component we have:

Gaussian (sigma = 1) | |

Gaussian (sigma = 8) | |

DxGaussian (sigma = 1) | |

DxGaussian (sigma = 8) | |

DyGaussian (sigma = 1) | |

DyGaussian (sigma = 8) | |

Laplacian of Gaussian (sigma = 1) | |

Laplacian of Gaussian (sigma = 8) |

## No comments:

## Post a Comment