Commit a476ec1c authored by Gregor Kovalcik's avatar Gregor Kovalcik

Implementation of PCT signature extractor (position-color-texture) and…

Implementation of PCT signature extractor (position-color-texture) and evaluation of their Signature Quadratic Form Distance (SQFD).
parent eb8f5b88
......@@ -92,3 +92,22 @@
booktitle = "Computer Vision and Pattern Recognition",
year = {2013}
}
@article{KrulisLS16,
author = {Martin Krulis and Jakub Lokoc and Tomas Skopal},
title = {Efficient extraction of clustering-based feature signatures using {GPU} architectures},
journal = {Multimedia Tools Appl.},
volume = {75},
number = {13},
pages = {8071--8103},
year = {2016}
}
@inproceedings{BeecksUS10,
author = {Christian Beecks and Merih Seran Uysal and Thomas Seidl},
title = {Signature Quadratic Form Distance},
booktitle = {{CIVR}},
pages = {438--445},
publisher = {{ACM}},
year = {2010}
}
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 8071–8103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace cv;
using namespace xfeatures2d;
void printHelpMessage(void);
void printHelpMessage(void)
{
cout << "Example of the PCTSignatures algorithm computing and visualizing\n"
"image signature for one image, or comparing multiple images with the first\n"
"image using the signature quadratic form distance.\n\n"
"Usage: pct_signatures ImageToProcessAndDisplay\n"
"or: pct_signatures ReferenceImage [ImagesToCompareWithTheReferenceImage]\n\n"
"The program has 2 modes:\n"
"- single argument: program computes and visualizes the image signature\n"
"- multiple arguments: program compares the first image to the others\n"
" using pct signatures and signature quadratic form distance (SQFD)";
}
/** @brief
Example of the PCTSignatures algorithm.
The program has 2 modes:
- single argument mode, where the program computes and visualizes the image signature
- multiple argument mode, where the program compares the first image to the others
using signatures and signature quadratic form distance (SQFD)
*/
int main(int argc, char** argv)
{
if (argc < 2) // Check arguments
{
printHelpMessage();
return 1;
}
Mat source;
source = imread(argv[1]); // Read the file
if (!source.data) // Check for invalid input
{
cerr << "Could not open or find the image: " << argv[1];
return -1;
}
Mat signature, result; // define variables
int initSampleCount = 2000;
int initSeedCount = 400;
int grayscaleBitsPerPixel = 4;
vector<Point2f> initPoints;
namedWindow("Source", WINDOW_AUTOSIZE); // Create windows for display.
namedWindow("Result", WINDOW_AUTOSIZE);
// create the algorithm
PCTSignatures::generateInitPoints(initPoints, initSampleCount, PCTSignatures::UNIFORM);
Ptr<PCTSignatures> pctSignatures = PCTSignatures::create(initPoints, initSeedCount);
pctSignatures->setGrayscaleBits(grayscaleBitsPerPixel);
// compute and visualize the first image
double start = (double)getTickCount();
pctSignatures->computeSignature(source, signature);
double end = (double)getTickCount();
cout << "Signature of the reference image computed in " << (end - start) / (getTickFrequency() * 1.0f) << " seconds." << endl;
PCTSignatures::drawSignature(source, signature, result);
imshow("Source", source); // show the result
imshow("Result", result);
if (argc == 2) // single image -> finish right after the visualization
{
waitKey(0); // Wait for user input
return 0;
}
// multiple images -> compare to the first one
else
{
vector<Mat> images;
vector<Mat> signatures;
vector<float> distances;
for (int i = 2; i < argc; i++)
{
Mat image = imread(argv[i]);
if (!source.data) // Check for invalid input
{
cerr << "Could not open or find the image: " << argv[i] << std::endl;
return 1;
}
images.push_back(image);
}
pctSignatures->computeSignatures(images, signatures);
Ptr<PCTSignaturesSQFD> pctSQFD = PCTSignaturesSQFD::create();
pctSQFD->computeQuadraticFormDistances(signature, signatures, distances);
for (int i = 0; i < (int)(distances.size()); i++)
{
cout << "Image: " << argv[i + 2] << ", similarity: " << distances[i] << endl;
}
waitKey(0); // Wait for user input
}
return 0;
}
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 8071–8103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace cv;
using namespace xfeatures2d;
void printHelpMessage(void);
void printHelpMessage(void)
{
cout << "Example of the PCTSignatures algorithm.\n\n"
"This program computes and visualizes position-color-texture signatures\n"
"using images from webcam if available.\n\n"
"Usage:\n"
"pct_webcam [sample_count] [seed_count]\n"
"Note: sample_count must be greater or equal to seed_count.";
}
/** @brief
Example of the PCTSignatures algorithm.
This program computes and visualizes position-color-texture signatures
of images taken from webcam if available.
*/
int main(int argc, char** argv)
{
// define variables
Mat frame, signature, result;
int initSampleCount = 2000;
int initSeedCount = 400;
int grayscaleBitsPerPixel = 4;
// parse for help argument
{
for (int i = 1; i < argc; i++)
{
if ((string)argv[i] == "-h" || (string)argv[i] == "--help")
{
printHelpMessage();
return 0;
}
}
}
// parse optional arguments
if (argc > 1) // sample count
{
initSampleCount = atoi(argv[1]);
if (initSampleCount <= 0)
{
cerr << "Sample count have to be a positive integer: " << argv[1] << endl;
return 1;
}
initSeedCount = (int)floor(initSampleCount / 4);
initSeedCount = std::max(1, initSeedCount); // fallback if sample count == 1
}
if (argc > 2) // seed count
{
initSeedCount = atoi(argv[2]);
if (initSeedCount <= 0)
{
cerr << "Seed count have to be a positive integer: " << argv[2] << endl;
return 1;
}
if (initSeedCount > initSampleCount)
{
cerr << "Seed count have to be lower or equal to sample count!" << endl;
return 1;
}
}
// create algorithm
Ptr<PCTSignatures> pctSignatures = PCTSignatures::create(initSampleCount, initSeedCount, PCTSignatures::UNIFORM);
pctSignatures->setGrayscaleBits(grayscaleBitsPerPixel);
// open video capture device
VideoCapture videoCapture;
if (!videoCapture.open(0))
{
cerr << "Unable to open the first video capture device with ID = 0!" << endl;
return 1;
}
// Create windows for display.
namedWindow("Source", WINDOW_AUTOSIZE);
namedWindow("Result", WINDOW_AUTOSIZE);
// run drawing loop
for (;;)
{
videoCapture >> frame;
if (frame.empty()) break; // end of video stream
pctSignatures->computeSignature(frame, signature);
PCTSignatures::drawSignature(Mat::zeros(frame.size(), frame.type()), signature, result);
imshow("Source", frame); // Show our images inside the windows.
imshow("Result", result);
if (waitKey(1) == 27) break; // stop videocapturing by pressing ESC
}
return 0;
}
This diff is collapsed.
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 8071–8103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#ifndef _OPENCV_XFEATURES_2D_PCT_SIGNATURES_CONSTANTS_HPP_
#define _OPENCV_XFEATURES_2D_PCT_SIGNATURES_CONSTANTS_HPP_
#ifdef __cplusplus
namespace cv
{
namespace xfeatures2d
{
namespace pct_signatures
{
const int SIGNATURE_DIMENSION = 8;
const int WEIGHT_IDX = 0;
const int X_IDX = 1;
const int Y_IDX = 2;
const int L_IDX = 3;
const int A_IDX = 4;
const int B_IDX = 5;
const int CONTRAST_IDX = 6;
const int ENTROPY_IDX = 7;
const float L_COLOR_RANGE = 100;
const float A_COLOR_RANGE = 127;
const float B_COLOR_RANGE = 127;
const float SAMPLER_CONTRAST_NORMALIZER = 25.0; // both determined empirically
const float SAMPLER_ENTROPY_NORMALIZER = 4.0;
}
}
}
#endif
#endif
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 8071–8103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#ifndef _OPENCV_XFEATURES_2D_PCT_SIGNATURES_DISTANCE_HPP_
#define _OPENCV_XFEATURES_2D_PCT_SIGNATURES_DISTANCE_HPP_
#ifdef __cplusplus
#include "precomp.hpp"
#include "constants.hpp"
namespace cv
{
namespace xfeatures2d
{
namespace pct_signatures
{
static inline float distanceL0_25(
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
float result = (float)0.0;
for (int d = 1; d < SIGNATURE_DIMENSION; ++d)
{
float difference = points1.at<float>(idx1, d) - points2.at<float>(idx2, d);
result += std::sqrt(std::sqrt(std::abs(difference)));
}
result *= result;
return result * result;
}
static inline float distanceL0_5(
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
float result = (float)0.0;
for (int d = 1; d < SIGNATURE_DIMENSION; ++d)
{
float difference = points1.at<float>(idx1, d) - points2.at<float>(idx2, d);
result += std::sqrt(std::abs(difference));
}
return result * result;
}
static inline float distanceL1(
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
float result = (float)0.0;
for (int d = 1; d < SIGNATURE_DIMENSION; ++d)
{
float difference = points1.at<float>(idx1, d) - points2.at<float>(idx2, d);
result += std::abs(difference);
}
return result;
}
static inline float distanceL2(
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
float result = (float)0.0;
for (int d = 1; d < SIGNATURE_DIMENSION; ++d)
{
float difference = points1.at<float>(idx1, d) - points2.at<float>(idx2, d);
result += difference * difference;
}
return (float)std::sqrt(result);
}
static inline float distanceL2Squared(
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
float result = (float)0.0;
for (int d = 1; d < SIGNATURE_DIMENSION; ++d)
{
float difference = points1.at<float>(idx1, d) - points2.at<float>(idx2, d);
result += difference * difference;
}
return result;
}
static inline float distanceL5(
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
float result = (float)0.0;
for (int d = 1; d < SIGNATURE_DIMENSION; ++d)
{
float difference = points1.at<float>(idx1, d) - points2.at<float>(idx2, d);
result += std::abs(difference) * difference * difference * difference * difference;
}
return std::pow(result, (float)0.2);
}
static inline float distanceLInfinity(
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
float result = (float)0.0;
for (int d = 1; d < SIGNATURE_DIMENSION; ++d)
{
float difference = points1.at<float>(idx1, d) - points2.at<float>(idx2, d);
if (difference > result)
{
result = difference;
}
}
return result;
}
/**
* @brief Computed distance between two centroids using given distance function.
* @param distanceFunction Distance function selector.
* @param points1 The first signature matrix - one centroid in each row.
* @param idx1 ID of centroid in the first signature
* @param points2 The second signature matrix - one centroid in each row.
* @param idx2 ID of centroid in the first signature
* @note The first column of a signature contains weights,
* so only rows 1 to SIGNATURE_DIMENSION are used.
*/
static inline float computeDistance(
const int distanceFunction,
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
switch (distanceFunction)
{
case PCTSignatures::L0_25:
return distanceL0_25(points1, idx1, points2, idx2);
case PCTSignatures::L0_5:
return distanceL0_5(points1, idx1, points2, idx2);
case PCTSignatures::L1:
return distanceL1(points1, idx1, points2, idx2);
case PCTSignatures::L2:
return distanceL2(points1, idx1, points2, idx2);
case PCTSignatures::L2SQUARED:
return distanceL2Squared(points1, idx1, points2, idx2);
case PCTSignatures::L5:
return distanceL5(points1, idx1, points2, idx2);
case PCTSignatures::L_INFINITY:
return distanceLInfinity(points1, idx1, points2, idx2);
default:
CV_Error(Error::StsBadArg, "Distance function not implemented!");
return -1;
}
}
}
}
}
#endif
#endif
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 80718103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#include "precomp.hpp"
#include "grayscale_bitmap.hpp"
namespace cv
{
namespace xfeatures2d
{
namespace pct_signatures
{
GrayscaleBitmap::GrayscaleBitmap(InputArray _bitmap, int bitsPerPixel)
: mBitsPerPixel(bitsPerPixel)
{
Mat bitmap = _bitmap.getMat();
if (bitmap.empty())
{
CV_Error(Error::StsBadArg, "Input bitmap is empty");
}
if (bitmap.depth() != CV_8U && bitmap.depth() != CV_16U)
{
CV_Error(Error::StsUnsupportedFormat, "Input bitmap depth must be CV_8U or CV_16U");
}
if (bitmap.depth() == CV_8U)
{
bitmap.convertTo(bitmap, CV_16U, 257);
}
Mat grayscaleBitmap;
cvtColor(bitmap, grayscaleBitmap, COLOR_BGR2GRAY);
mWidth = bitmap.cols;
mHeight = bitmap.rows;
if (bitsPerPixel <= 0 || bitsPerPixel > 8)
{
CV_Error_(Error::StsBadArg, ("Invalid number of bits per pixel %d. Only values in range [1..8] are accepted.", bitsPerPixel));
}
// Allocate space for pixel data.
int pixelsPerItem = 32 / mBitsPerPixel;
mData.resize((mWidth*mHeight + pixelsPerItem - 1) / pixelsPerItem);
// Convert the bitmap to grayscale and fill the pixel data.
CV_Assert(grayscaleBitmap.depth() == CV_16U);
for (int y = 0; y < mHeight; y++)
{
for (int x = 0; x < mWidth; x++)
{
uint grayVal = ((uint)grayscaleBitmap.at<ushort>((int)y, (int)x)) >> (16 - mBitsPerPixel);
setPixel(x, y, grayVal);
}
}
// Prepare the preallocated contrast matrix for contrast-entropy computations
mCoOccurrenceMatrix.resize(1 << (mBitsPerPixel * 2)); // mCoOccurrenceMatrix size = maxPixelValue^2
}
// HOT PATH 30%
void GrayscaleBitmap::getContrastEntropy(int x, int y, float& contrast, float& entropy, int radius)
{
int fromX = (x > radius) ? x - radius : 0;
int fromY = (y > radius) ? y - radius : 0;
int toX = std::min<int>(mWidth - 1, x + radius + 1);
int toY = std::min<int>(mHeight - 1, y + radius + 1);
for (int j = fromY; j < toY; ++j)
{
for (int i = fromX; i < toX; ++i) // for each pixel in the window
{
updateCoOccurrenceMatrix(getPixel(i, j), getPixel(i, j + 1)); // match every pixel with all 8 its neighbours
updateCoOccurrenceMatrix(getPixel(i, j), getPixel(i + 1, j));
updateCoOccurrenceMatrix(getPixel(i, j), getPixel(i + 1, j + 1));
updateCoOccurrenceMatrix(getPixel(i + 1, j), getPixel(i, j + 1)); // 4 updates per pixel in the window
}
}
contrast = 0.0;
entropy = 0.0;
uint pixelsScale = 1 << mBitsPerPixel;
float normalizer = (float)((toX - fromX) * (toY - fromY) * 4); // four increments per pixel in the window (see above)
for (int j = 0; j < (int)pixelsScale; ++j) // iterate row in a 2D histogram
{
for (int i = 0; i <= j; ++i) // iterate column up to the diagonal in 2D histogram
{
if (mCoOccurrenceMatrix[j*pixelsScale + i] != 0) // consider only non-zero values
{
float value = (float)mCoOccurrenceMatrix[j*pixelsScale + i] / normalizer; // normalize value by number of histogram updates
contrast += (i - j) * (i - j) * value; // compute contrast
entropy -= value * std::log(value); // compute entropy
mCoOccurrenceMatrix[j*pixelsScale + i] = 0; // clear the histogram array for the next computation
}
}
}
}
void GrayscaleBitmap::convertToMat(OutputArray _bitmap, bool normalize) const
{
_bitmap.create((int)getHeight(), (int)getWidth(), CV_8U);
Mat bitmap = _bitmap.getMat();
for (int y = 0; y < getHeight(); ++y)
{
for (int x = 0; x < getWidth(); ++x)
{
uint pixel = getPixel(x, y);
if (normalize && mBitsPerPixel < 8)
{
pixel <<= 8 - mBitsPerPixel;
}
else if (normalize && mBitsPerPixel > 8)
{
pixel >>= mBitsPerPixel - 8;
}
bitmap.at<uchar>((int)y, (int)x) = (uchar)pixel;
}
}
}
}
}
}
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 8071–8103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#ifndef _OPENCV_XFEATURES_2D_PCT_SIGNATURES_GRAYSCALE_BITMAP_HPP_
#define _OPENCV_XFEATURES_2D_PCT_SIGNATURES_GRAYSCALE_BITMAP_HPP_
#ifdef __cplusplus
namespace cv
{
namespace xfeatures2d
{
namespace pct_signatures
{
/**
* @brief Specific implementation of grayscale bitmap. This bitmap is used
* to compute contrast and entropy features from surroundings of a pixel.
*/
class GrayscaleBitmap
{
public:
/**
* @brief Initialize the grayscale bitmap from regular bitmap.
* @param bitmap Bitmap used as source of data.
* @param bitsPerPixel How many bits occupy one pixel in grayscale (e.g., 8 ~ 256 grayscale values).
* Must be within [1..8] range.
*/
GrayscaleBitmap(InputArray bitmap, int bitsPerPixel = 4);
/**
* @brief Return the width of the image in pixels.
*/
int getWidth() const
{
return mWidth;
}
/**
* @brief Return the height of the image in pixels.
*/
int getHeight() const
{
return mHeight;
}
/**
* @brief Return the height of the image in pixels.
*/
int getBitsPerPixel() const
{
return mBitsPerPixel;
}
/**
* @brief Compute contrast and entropy at selected coordinates.
* @param x The horizontal coordinate of the pixel (0..width-1).
* @param y The vertical coordinate of the pixel (0..height-1).
* @param contrast Output variable where contrast value is saved.
* @param entropy Output variable where entropy value is saved.
* @param radius Radius of the rectangular window around selected pixel used for computing
* contrast and entropy. Size of the window side is (2*radius + 1).
* The window is cropped if [x,y] is too near the image border.
*/
void getContrastEntropy(
int x,
int y,
float& contrast,
float& entropy,
int windowRadius = 3);
/**
* @brief Converts to OpenCV CV_8U Mat for debug and visualization purposes.
* @param bitmap OutputArray proxy where Mat will be written.
* @param normalize Whether to normalize the bitmap to the whole range of 255 values
* to improve contrast.
*/
void convertToMat(OutputArray bitmap, bool normalize = true) const;
private:
/**
* @brief Width of the image.
*/
int mWidth;
/**
* @brief Height of the image.
*/
int mHeight;
/**
* @brief Number of bits per pixel.
*/
int mBitsPerPixel;
/**
* @brief Pixel data packed in 32-bit uints.
*/
std::vector<uint> mData;
/**
* @brief Tmp matrix used for computing contrast and entropy.
*/
std::vector<uint> mCoOccurrenceMatrix;
/**
* @brief Get pixel from packed data vector.
* @param x The horizontal coordinate of the pixel (0..width-1).
* @param y The vertical coordinate of the pixel (0..height-1).
* @return Grayscale value (0 ~ black, 2^bitPerPixel - 1 ~ white).
*/
uint inline getPixel(int x, int y) const
{
int pixelsPerItem = 32 / mBitsPerPixel;
int offset = y*mWidth + x;
int shift = (offset % pixelsPerItem) * mBitsPerPixel;
uint mask = (1 << mBitsPerPixel) - 1;
return (mData[offset / pixelsPerItem] >> shift) & mask;
}
/**
* @brief Set pixel in the packed data vector.
* @param x The horizontal coordinate of the pixel (0..width-1).
* @param y The vertical coordinate of the pixel (0..height-1).
* @param val Grayscale value (0 ~ black, 2^bitPerPixel - 1 ~ white).
*/
void inline setPixel(int x, int y, uint val)
{
int pixelsPerItem = 32 / mBitsPerPixel;
int offset = y*mWidth + x;
int shift = (offset % pixelsPerItem) * mBitsPerPixel;
uint mask = (1 << mBitsPerPixel) - 1;
val &= mask;
mData[offset / pixelsPerItem] &= ~(mask << shift);
mData[offset / pixelsPerItem] |= val << shift;
}
/**
* @brief Perform an update of contrast matrix.
*/
void inline updateCoOccurrenceMatrix(uint a, uint b)
{
// co-occurrence matrix is symmetric
// merge to a variable with greater higher bits
// to accumulate just in upper triangle in co-occurrence matrix for efficiency
int offset = (int)((a > b) ? (a << mBitsPerPixel) + b : a + (b << mBitsPerPixel));
mCoOccurrenceMatrix[offset]++;
}
};
}
}
}
#endif
#endif
This diff is collapsed.
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 8071–8103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#ifndef _OPENCV_XFEATURES_2D_PCT_SIGNATURES_CLUSTERIZER_HPP_
#define _OPENCV_XFEATURES_2D_PCT_SIGNATURES_CLUSTERIZER_HPP_
#ifdef __cplusplus
#include "constants.hpp"
#include "distance.hpp"
namespace cv
{
namespace xfeatures2d
{
namespace pct_signatures
{
class PCTClusterizer : public Algorithm
{
public:
static Ptr<PCTClusterizer> create(
const std::vector<int>& initSeedIndexes,
int iterations = 10,
int maxClusters = 768, // max for Fermi GPU architecture
int clusterMinSize = 2,
float joiningDistance = 0.2,
float dropThreshold = 0,
int distanceFunction = PCTSignatures::L2);
/**** Accessors ****/
virtual int getIterationCount() const = 0;
virtual std::vector<int> getInitSeedIndexes() const = 0;
virtual int getMaxClustersCount() const = 0;
virtual int getClusterMinSize() const = 0;
virtual float getJoiningDistance() const = 0;
virtual float getDropThreshold() const = 0;
virtual int getDistanceFunction() const = 0;
virtual void setIterationCount(int iterationCount) = 0;
virtual void setInitSeedIndexes(std::vector<int> initSeedIndexes) = 0;
virtual void setMaxClustersCount(int maxClustersCount) = 0;
virtual void setClusterMinSize(int clusterMinSize) = 0;
virtual void setJoiningDistance(float joiningDistance) = 0;
virtual void setDropThreshold(float dropThreshold) = 0;
virtual void setDistanceFunction(int distanceFunction) = 0;
/**
* @brief K-means algorithm over the sampled points producing centroids as signatures.
* @param samples List of sampled points.
* @param signature Output list of computed centroids - the signature of the image.
*/
virtual void clusterize(InputArray samples, OutputArray signature) = 0;
};
}
}
}
#endif
#endif
This diff is collapsed.
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 8071–8103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#ifndef _OPENCV_XFEATURES_2D_PCT_SIGNATURES_SAMPLER_HPP_
#define _OPENCV_XFEATURES_2D_PCT_SIGNATURES_SAMPLER_HPP_
#ifdef __cplusplus
#include "constants.hpp"
#include "grayscale_bitmap.hpp"
namespace cv
{
namespace xfeatures2d
{
namespace pct_signatures
{
class PCTSampler : public Algorithm
{
public:
static Ptr<PCTSampler> create(
const std::vector<Point2f>& initSamplingPoints,
int grayscaleBits = 4,
int windowRadius = 3);
/**
* @brief Sampling algorithm that produces samples of the input image
* using the stored sampling point locations.
* @param image Input image.
* @param signature Output list of computed image samples.
*/
virtual void sample(InputArray image, OutputArray samples) const = 0;
/**** accessors ****/
virtual int getSampleCount() const = 0;
virtual int getGrayscaleBits() const = 0;
virtual int getWindowRadius() const = 0;
virtual float getWeightX() const = 0;
virtual float getWeightY() const = 0;
virtual float getWeightL() const = 0;
virtual float getWeightA() const = 0;
virtual float getWeightB() const = 0;
virtual float getWeightConstrast() const = 0;
virtual float getWeightEntropy() const = 0;
virtual std::vector<Point2f> getSamplingPoints() const = 0;
virtual void setGrayscaleBits(int grayscaleBits) = 0;
virtual void setWindowRadius(int radius) = 0;
virtual void setWeightX(float weight) = 0;
virtual void setWeightY(float weight) = 0;
virtual void setWeightL(float weight) = 0;
virtual void setWeightA(float weight) = 0;
virtual void setWeightB(float weight) = 0;
virtual void setWeightContrast(float weight) = 0;
virtual void setWeightEntropy(float weight) = 0;
virtual void setWeight(int idx, float value) = 0;
virtual void setWeights(const std::vector<float>& weights) = 0;
virtual void setTranslation(int idx, float value) = 0;
virtual void setTranslations(const std::vector<float>& translations) = 0;
virtual void setSamplingPoints(std::vector<Point2f> samplingPoints) = 0;
};
}
}
}
#endif
#endif
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 8071–8103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#ifndef _OPENCV_XFEATURES_2D_PCT_SIGNATURES_SIMILARITY_HPP_
#define _OPENCV_XFEATURES_2D_PCT_SIGNATURES_SIMILARITY_HPP_
#ifdef __cplusplus
#include "precomp.hpp"
#include "distance.hpp"
namespace cv
{
namespace xfeatures2d
{
namespace pct_signatures
{
static inline float minusSimilarity(
const int distancefunction,
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
return -computeDistance(distancefunction, points1, idx1, points2, idx2);
}
static inline float gaussianSimilarity(
const int distancefunction,
const float alpha,
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
float distance = computeDistance(distancefunction, points1, idx1, points2, idx2);
return exp(-alpha + distance * distance);
}
static inline float heuristicSimilarity(
const int distancefunction,
const float alpha,
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
return 1 / (alpha + computeDistance(distancefunction, points1, idx1, points2, idx2));
}
static inline float computeSimilarity(
const int distancefunction,
const int similarity,
const float similarityParameter,
const Mat& points1, int idx1,
const Mat& points2, int idx2)
{
switch (similarity)
{
case PCTSignatures::MINUS:
return minusSimilarity(distancefunction, points1, idx1, points2, idx2);
case PCTSignatures::GAUSSIAN:
return gaussianSimilarity(distancefunction, similarityParameter, points1, idx1, points2, idx2);
case PCTSignatures::HEURISTIC:
return heuristicSimilarity(distancefunction, similarityParameter, points1, idx1, points2, idx2);
default:
CV_Error(Error::StsNotImplemented, "Similarity function not implemented!");
return -1;
}
}
}
}
}
#endif
#endif
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
/*
Contributed by Gregor Kovalcik <gregor dot kovalcik at gmail dot com>
based on code provided by Martin Krulis, Jakub Lokoc and Tomas Skopal.
References:
Martin Krulis, Jakub Lokoc, Tomas Skopal.
Efficient Extraction of Clustering-Based Feature Signatures Using GPU Architectures.
Multimedia tools and applications, 75(13), pp.: 80718103, Springer, ISSN: 1380-7501, 2016
Christian Beecks, Merih Seran Uysal, Thomas Seidl.
Signature quadratic form distance.
In Proceedings of the ACM International Conference on Image and Video Retrieval, pages 438-445.
ACM, 2010.
*/
#include "precomp.hpp"
#include "pct_signatures/constants.hpp"
#include "pct_signatures/similarity.hpp"
namespace cv
{
namespace xfeatures2d
{
namespace pct_signatures
{
class PCTSignaturesSQFD_Impl : public PCTSignaturesSQFD
{
public:
PCTSignaturesSQFD_Impl(
const int distanceFunction,
const int similarityFunction,
const float similarityParameter)
: mDistanceFunction(distanceFunction),
mSimilarityFunction(similarityFunction),
mSimilarityParameter(similarityParameter)
{
}
float computeQuadraticFormDistance(
InputArray _signature0,
InputArray _signature1) const;
void computeQuadraticFormDistances(
const Mat& sourceSignature,
const std::vector<Mat>& imageSignatures,
std::vector<float>& distances) const;
private:
int mDistanceFunction;
int mSimilarityFunction;
float mSimilarityParameter;
float computePartialSQFD(
const Mat& signature0,
const Mat& signature1) const;
};
/**
* @brief Class implementing parallel computing of SQFD distance for multiple images.
*/
class Parallel_computeSQFDs : public ParallelLoopBody
{
private:
const PCTSignaturesSQFD* mPctSignaturesSQFDAlgorithm;
const Mat* mSourceSignature;
const std::vector<Mat>* mImageSignatures;
std::vector<float>* mDistances;
public:
Parallel_computeSQFDs(
const PCTSignaturesSQFD* pctSignaturesSQFDAlgorithm,
const Mat* sourceSignature,
const std::vector<Mat>* imageSignatures,
std::vector<float>* distances)
: mPctSignaturesSQFDAlgorithm(pctSignaturesSQFDAlgorithm),
mSourceSignature(sourceSignature),
mImageSignatures(imageSignatures),
mDistances(distances)
{
mDistances->resize(imageSignatures->size());
}
void operator()(const Range& range) const
{
if (mSourceSignature->empty())
{
CV_Error(Error::StsBadArg, "Source signature is empty!");
}
for (int i = range.start; i < range.end; i++)
{
if (mImageSignatures[i].empty())
{
CV_Error_(Error::StsBadArg, ("Signature ID: %d is empty!", i));
}
(*mDistances)[i] = mPctSignaturesSQFDAlgorithm->computeQuadraticFormDistance(
*mSourceSignature, (*mImageSignatures)[i]);
}
}
};
float PCTSignaturesSQFD_Impl::computeQuadraticFormDistance(
InputArray _signature0,
InputArray _signature1) const
{
// check input
if (_signature0.empty() || _signature1.empty())
{
CV_Error(Error::StsBadArg, "Empty signature!");
}
Mat signature0 = _signature0.getMat();
Mat signature1 = _signature1.getMat();
if (signature0.cols != SIGNATURE_DIMENSION || signature1.cols != SIGNATURE_DIMENSION)
{
CV_Error_(Error::StsBadArg, ("Signature dimension must be %d!", SIGNATURE_DIMENSION));
}
if (signature0.rows <= 0 || signature1.rows <= 0)
{
CV_Error(Error::StsBadArg, "Signature count must be greater than 0!");
}
// compute sqfd
float result = 0;
result += computePartialSQFD(signature0, signature0);
result += computePartialSQFD(signature1, signature1);
result -= computePartialSQFD(signature0, signature1) * 2;
return sqrt(result);
}
void PCTSignaturesSQFD_Impl::computeQuadraticFormDistances(
const Mat& sourceSignature,
const std::vector<Mat>& imageSignatures,
std::vector<float>& distances) const
{
parallel_for_(Range(0, (int)imageSignatures.size()),
Parallel_computeSQFDs(this, &sourceSignature, &imageSignatures, &distances));
}
float PCTSignaturesSQFD_Impl::computePartialSQFD(
const Mat& signature0,
const Mat& signature1) const
{
float result = 0;
for (int i = 0; i < signature0.rows; i++)
{
for (int j = 0; j < signature1.rows; j++)
{
result += signature0.at<float>(i, WEIGHT_IDX) * signature1.at<float>(j, WEIGHT_IDX)
* computeSimilarity(mDistanceFunction, mSimilarityFunction, mSimilarityParameter, signature0, i, signature1, j);
}
}
return result;
}
}// end of namespace pct_signatures
Ptr<PCTSignaturesSQFD> PCTSignaturesSQFD::create(
const int distanceFunction,
const int similarityFunction,
const float similarityParameter)
{
return makePtr<pct_signatures::PCTSignaturesSQFD_Impl>(distanceFunction, similarityFunction, similarityParameter);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment