fuzzy_F0_math.cpp 10.1 KB
Newer Older
tucna's avatar
tucna committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  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
//
// Copyright (C) 2015, University of Ostrava, Institute for Research and Applications of Fuzzy Modeling,
// Pavel Vlasanek, 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:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's 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.
//
//   * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/

#include "precomp.hpp"

using namespace cv;

void ft::FT02D_components(InputArray matrix, InputArray kernel, OutputArray components, InputArray mask)
{
48
    CV_Assert(matrix.channels() == kernel.channels() && mask.channels() == 1);
tucna's avatar
tucna committed
49

50 51 52 53
    int radiusX = (kernel.cols() - 1) / 2;
    int radiusY = (kernel.rows() - 1) / 2;
    int An = matrix.cols() / radiusX + 1;
    int Bn = matrix.rows() / radiusY + 1;
tucna's avatar
tucna committed
54 55 56 57

    Mat matrixPadded;
    Mat maskPadded;

58 59 60 61
    copyMakeBorder(matrix, matrixPadded, radiusY, kernel.rows(), radiusX, kernel.cols(), BORDER_CONSTANT, Scalar(0));
    copyMakeBorder(mask, maskPadded, radiusY, kernel.rows(), radiusX, kernel.cols(), BORDER_CONSTANT, Scalar(0));

    components.create(Bn, An, CV_MAKETYPE(CV_32F, matrix.channels()));
tucna's avatar
tucna committed
62 63 64 65 66 67 68 69 70

    Mat componentsMat = components.getMat();

    for (int i = 0; i < An; i++)
    {
        for (int o = 0; o < Bn; o++)
        {
            int centerX = (i * radiusX) + radiusX;
            int centerY = (o * radiusY) + radiusY;
71
            Rect area(centerX - radiusX, centerY - radiusY, kernel.cols(), kernel.rows());
tucna's avatar
tucna committed
72 73 74 75 76

            Mat roiImage(matrixPadded, area);
            Mat roiMask(maskPadded, area);
            Mat kernelMasked;

77
            kernel.copyTo(kernelMasked, roiMask);
tucna's avatar
tucna committed
78 79 80 81

            Mat numerator;
            multiply(roiImage, kernelMasked, numerator, 1, CV_32F);

82 83 84 85
            Scalar value;
            divide(sum(numerator), sum(kernelMasked), value, 1, CV_32F);

            componentsMat.row(o).col(i).setTo(value);
tucna's avatar
tucna committed
86 87 88 89 90 91 92 93 94 95 96 97 98
        }
    }
}

void ft::FT02D_components(InputArray matrix, InputArray kernel, OutputArray components)
{
    Mat mask = Mat::ones(matrix.size(), CV_8U);

    ft::FT02D_components(matrix, kernel, components, mask);
}

void ft::FT02D_inverseFT(InputArray components, InputArray kernel, OutputArray output, int width, int height)
{
99
    CV_Assert(components.channels() == 1 && kernel.channels() == 1);
tucna's avatar
tucna committed
100

101
    Mat componentsMat = components.getMat();
tucna's avatar
tucna committed
102

103 104 105 106
    int radiusX = (kernel.cols() - 1) / 2;
    int radiusY = (kernel.rows() - 1) / 2;
    int outputWidthPadded = radiusX + width + kernel.cols();
    int outputHeightPadded = radiusY + height + kernel.rows();
tucna's avatar
tucna committed
107 108 109

    output.create(height, width, CV_32F);

110
    Mat outputZeroes(outputHeightPadded, outputWidthPadded, CV_32F, Scalar(0));
tucna's avatar
tucna committed
111 112 113 114 115 116 117

    for (int i = 0; i < componentsMat.cols; i++)
    {
        for (int o = 0; o < componentsMat.rows; o++)
        {
            int centerX = (i * radiusX) + radiusX;
            int centerY = (o * radiusY) + radiusY;
118 119 120 121 122 123
            Rect area(centerX - radiusX, centerY - radiusY, kernel.cols(), kernel.rows());

            float component = componentsMat.at<float>(o, i);

            Mat inverse;
            multiply(kernel, component, inverse, 1, CV_32F);
tucna's avatar
tucna committed
124 125

            Mat roiOutput(outputZeroes, area);
126
            add(roiOutput, inverse, roiOutput);
tucna's avatar
tucna committed
127 128 129 130 131 132
        }
    }

    outputZeroes(Rect(radiusX, radiusY, width, height)).copyTo(output);
}

133 134 135 136 137 138 139 140
void ft::FT02D_process(InputArray matrix, InputArray kernel, OutputArray output)
{
    Mat mask = Mat::ones(matrix.size(), CV_8U);

    ft::FT02D_process(matrix, kernel, output, mask);
}

void ft::FT02D_process(InputArray matrix, InputArray kernel, OutputArray output, InputArray mask)
tucna's avatar
tucna committed
141
{
142
    CV_Assert(matrix.channels() == kernel.channels() && mask.channels() == 1);
tucna's avatar
tucna committed
143

144 145 146 147 148 149
    int radiusX = (kernel.cols() - 1) / 2;
    int radiusY = (kernel.rows() - 1) / 2;
    int An = matrix.cols() / radiusX + 1;
    int Bn = matrix.rows() / radiusY + 1;
    int outputWidthPadded = radiusX + matrix.cols() + kernel.cols();
    int outputHeightPadded = radiusY + matrix.rows() + kernel.rows();
tucna's avatar
tucna committed
150

151
    Mat matrixPadded;
tucna's avatar
tucna committed
152 153
    Mat maskPadded;

154 155 156
    output.create(matrix.size(), CV_MAKETYPE(CV_32F, matrix.channels()));

    Mat outputZeroes(outputHeightPadded, outputWidthPadded, output.type(), Scalar(0));
tucna's avatar
tucna committed
157

158 159
    copyMakeBorder(matrix, matrixPadded, radiusY, kernel.rows(), radiusX, kernel.cols(), BORDER_CONSTANT, Scalar(0));
    copyMakeBorder(mask, maskPadded, radiusY, kernel.rows(), radiusX, kernel.cols(), BORDER_CONSTANT, Scalar(0));
tucna's avatar
tucna committed
160 161 162 163 164 165 166

    for (int i = 0; i < An; i++)
    {
        for (int o = 0; o < Bn; o++)
        {
            int centerX = (i * radiusX) + radiusX;
            int centerY = (o * radiusY) + radiusY;
167
            Rect area(centerX - radiusX, centerY - radiusY, kernel.cols(), kernel.rows());
tucna's avatar
tucna committed
168

169
            Mat roiMatrix(matrixPadded, area);
tucna's avatar
tucna committed
170 171 172 173 174 175
            Mat roiMask(maskPadded, area);
            Mat kernelMasked;

            kernel.copyTo(kernelMasked, roiMask);

            Mat numerator;
176
            multiply(roiMatrix, kernelMasked, numerator, 1, CV_32F);
tucna's avatar
tucna committed
177 178 179 180 181 182 183

            Scalar component;
            divide(sum(numerator), sum(kernelMasked), component, 1, CV_32F);

            Mat inverse;
            multiply(kernel, component, inverse, 1, CV_32F);

184
            Mat roiOutput(outputZeroes, area);
tucna's avatar
tucna committed
185 186 187 188
            add(roiOutput, inverse, roiOutput);
        }
    }

189
    outputZeroes(Rect(radiusX, radiusY, matrix.cols(), matrix.rows())).copyTo(output);
tucna's avatar
tucna committed
190 191
}

192
int ft::FT02D_iteration(InputArray matrix, InputArray kernel, OutputArray output, InputArray mask, OutputArray maskOutput, bool firstStop)
tucna's avatar
tucna committed
193
{
194 195 196 197 198 199 200 201
    CV_Assert(matrix.channels() == kernel.channels() && mask.channels() == 1);

    int radiusX = (kernel.cols() - 1) / 2;
    int radiusY = (kernel.rows() - 1) / 2;
    int An = matrix.cols() / radiusX + 1;
    int Bn = matrix.rows() / radiusY + 1;
    int outputWidthPadded = radiusX + matrix.cols() + kernel.cols();
    int outputHeightPadded = radiusY + matrix.rows() + kernel.rows();
tucna's avatar
tucna committed
202 203
    int undefinedComponents = 0;

204 205
    output.create(matrix.size(), CV_MAKETYPE(CV_32F, matrix.channels()));
    output.setTo(0);
tucna's avatar
tucna committed
206

207 208 209 210 211
    if (maskOutput.needed())
    {
        maskOutput.create(mask.rows(), mask.cols(), CV_8UC1);
        maskOutput.setTo(1);
    }
tucna's avatar
tucna committed
212

213 214 215 216 217 218 219 220
    Mat matrixOutputMat = Mat::zeros(outputHeightPadded, outputWidthPadded, CV_MAKETYPE(CV_32F, matrix.channels()));
    Mat maskOutputMat = Mat::ones(outputHeightPadded, outputWidthPadded, CV_8UC1);

    Mat matrixPadded;
    Mat maskPadded;

    copyMakeBorder(matrix, matrixPadded, radiusY, kernel.rows(), radiusX, kernel.cols(), BORDER_CONSTANT, Scalar(0));
    copyMakeBorder(mask, maskPadded, radiusY, kernel.rows(), radiusX, kernel.cols(), BORDER_CONSTANT, Scalar(0));
tucna's avatar
tucna committed
221 222 223 224 225 226 227

    for (int i = 0; i < An; i++)
    {
        for (int o = 0; o < Bn; o++)
        {
            int centerX = (i * radiusX) + radiusX;
            int centerY = (o * radiusY) + radiusY;
228
            Rect area(centerX - radiusX, centerY - radiusY, kernel.cols(), kernel.rows());
tucna's avatar
tucna committed
229

230
            Mat roiMatrix(matrixPadded, area);
tucna's avatar
tucna committed
231 232 233 234 235 236
            Mat roiMask(maskPadded, area);
            Mat kernelMasked;

            kernel.copyTo(kernelMasked, roiMask);

            Mat numerator;
237
            multiply(roiMatrix, kernelMasked, numerator, 1, CV_32F);
tucna's avatar
tucna committed
238 239 240 241 242 243 244

            Scalar denominator = sum(kernelMasked);

            if (denominator[0] == 0)
            {
                if (firstStop)
                {
245 246
                    matrixOutputMat = matrixPadded(Rect(radiusX, radiusY, matrix.cols(), matrix.rows()));
                    maskOutputMat = maskPadded(Rect(radiusX, radiusY, matrix.cols(), matrix.rows()));
tucna's avatar
tucna committed
247 248 249 250 251 252 253

                    return -1;
                }
                else
                {
                    undefinedComponents++;

254 255
                    Mat roiMaskOutput(maskOutputMat, Rect(centerX - radiusX + 1, centerY - radiusY + 1, kernel.cols() - 2, kernel.rows() - 2));
                    roiMaskOutput.setTo(0);
tucna's avatar
tucna committed
256 257 258 259 260 261 262 263 264 265 266

                    continue;
                }
            }

            Scalar component;
            divide(sum(numerator), denominator, component, 1, CV_32F);

            Mat inverse;
            multiply(kernel, component, inverse, 1, CV_32F);

267 268
            Mat roiMatrixOutput(matrixOutputMat, area);
            add(roiMatrixOutput, inverse, roiMatrixOutput);
tucna's avatar
tucna committed
269 270 271
        }
    }

272 273 274 275 276 277
    matrixOutputMat(Rect(radiusX, radiusY, matrix.cols(), matrix.rows())).copyTo(output);

    if (maskOutput.needed())
    {
        maskOutputMat(Rect(radiusX, radiusY, matrix.cols(), matrix.rows())).copyTo(maskOutput);
    }
tucna's avatar
tucna committed
278 279 280

    return undefinedComponents;
}