Commit 0fd48235 authored by Bellaktris's avatar Bellaktris

colorbalance module added, now it contains the only WHITE_BALANCE_SIMPLE implementation

parent 62c4145c
......@@ -111,11 +111,10 @@ Explanation
return -1;
}
2. **Convert source image to [0;1] range and RGB colospace**
2. **Convert source image to [0;1] range**
.. code-block:: cpp
cv::cvtColor(image, image, CV_BGR2RGB);
image.convertTo(image, cv::DataType<float>::type, 1/255.0);
3. **Run main algorithm**
......
set(the_description "Color balance algorithms")
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
ocv_define_module(colorbalance opencv_core opencv_imgproc OPTIONAL opencv_highgui)
\ No newline at end of file
********************************************
colorbalance. Color balance
********************************************
.. toctree::
:maxdepth: 2
Color balance <colorbalance/whitebalance>
Automatic white balance correction
**********************************
.. highlight:: cpp
balanceWhite
------------
.. ocv:function:: (const Mat &src, Mat &dst, const int algorithmType,
const float inputMin = 0.0f, const float inputMax = 255.0f,
const float outputMin = 0.0f, const float outputMax = 255.0f);
The function implements different algorithm of automatic white balance, i.e.
it tries to map image's white color to perceptual white (this can be violated
due to specific illumination or camera settings).
:param src : source image
:param dst : destination image
:param algorithmType : type of the algorithm to use.
Use WHITE_BALANCE_SIMPLE to perform
smart histogram adjustments
(ignoring 4% pixels with minimal
and maximal values) for each channel.
:param inputMin : minimum value in the input image
:param inputMax : maximum value in the input image
:param outputMin : minimum value in the output image
:param outputMax : maximum value in the output image
.. seealso::
:ocv:class:`cvtColor`,
:ocv:class:`equalizeHist`
\ No newline at end of file
/*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) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage 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:
//
// * 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*/
#ifndef __OPENCV_EDGEDETECTION_HPP__
#define __OPENCV_EDGEDETECTION_HPP__
#include "opencv2/core.hpp"
#include "opencv2/colorbalance/simple_color_balance.hpp"
#endif
/*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) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage 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:
//
// * 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*/
#ifndef __OPENCV_SIMPLE_COLOR_BALANCE_HPP__
#define __OPENCV_SIMPLE_COLOR_BALANCE_HPP__
/*
* simple_color_balance.hpp
*
* Created on: Jun 26, 2014
* Author: Yury Gitman
*/
#include <opencv2/core.hpp>
/*! \namespace cv
Namespace where all the C++ OpenCV functionality resides
*/
namespace cv
{
//! various white balance algorithms
enum
{
WHITE_BALANCE_SIMPLE = 0,
WHITE_BALANCE_GRAYWORLD = 1
};
/*! This function implements different white balance algorithms
* \param src : source image
* \param dst : destination image
* \param algorithmType : type of the algorithm to use
* \param inputMin : minimum input value
* \param inputMax : maximum output value
* \param outputMin : minimum input value
* \param outputMax : maximum output value
*/
CV_EXPORTS_W void balanceWhite(const Mat &src, Mat &dst, const int algorithmType,
const float inputMin = 0.0f, const float inputMax = 255.0f,
const float outputMin = 0.0f, const float outputMax = 255.0f);
}
#endif // __OPENCV_SIMPLE_COLOR_BALANCE_HPP__
\ No newline at end of file
#include "opencv2/colorbalance.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc/types_c.h"
const char* keys =
{
"{i || input image name}"
"{o || output image name}"
};
int main( int argc, const char** argv )
{
bool printHelp = ( argc == 1 );
printHelp = printHelp || ( argc == 2 && std::string(argv[1]) == "--help" );
printHelp = printHelp || ( argc == 2 && std::string(argv[1]) == "-h" );
if ( printHelp )
{
printf("\nThis sample demonstrates simple color balance algorithm\n"
"Call:\n"
" simple_color_blance -i=in_image_name [-o=out_image_name]\n\n");
return 0;
}
cv::CommandLineParser parser(argc, argv, keys);
if ( !parser.check() )
{
parser.printErrors();
return -1;
}
std::string inFilename = parser.get<std::string>("i");
std::string outFilename = parser.get<std::string>("o");
cv::Mat src = cv::imread(inFilename, 1);
if ( src.empty() )
{
printf("Cannot read image file: %s\n", inFilename.c_str());
return -1;
}
cv::Mat res(src.size(), src.type());
cv::balanceWhite(src, res, cv::WHITE_BALANCE_SIMPLE);
if ( outFilename == "" )
{
cv::namedWindow("after white balance", 1);
cv::imshow("after white balance", res);
cv::waitKey(0);
}
else
cv::imwrite(outFilename, res);
return 0;
}
\ No newline at end of file
/*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) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// * 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 Intel Corporation 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 <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
#include "opencv2/colorbalance.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/core/types.hpp"
#include "opencv2/core/types_c.h"
namespace cv
{
template <typename T>
void balanceWhite(std::vector < Mat_<T> > &src, Mat &dst,
const float inputMin, const float inputMax,
const float outputMin, const float outputMax, const int algorithmType)
{
switch ( algorithmType )
{
case WHITE_BALANCE_SIMPLE:
{
/********************* Simple white balance *********************/
float s1 = 2.0f; // low quantile
float s2 = 2.0f; // high quantile
int depth = 2; // depth of histogram tree
if (src[0].depth() != CV_8U)
++depth;
int bins = 16; // number of bins at each histogram level
int nElements = int( pow(bins, depth) );
// number of elements in histogram tree
for (size_t i = 0; i < src.size(); ++i)
{
std::vector <int> hist(nElements, 0);
Mat_<T>::iterator beginIt = src[i].begin();
Mat_<T>::iterator endIt = src[i].end();
for (Mat_<T>::iterator it = beginIt; it != endIt; ++it)
// histogram filling
{
int pos = 0;
float minValue = inputMin - 0.5f;
float maxValue = inputMax + 0.5f;
T val = *it;
float interval = float(maxValue - minValue) / bins;
for (int j = 0; j < depth; ++j)
{
int currentBin = (val - minValue + 1e-4) / interval;
++hist[pos + currentBin];
pos = (pos + currentBin)*bins;
minValue = minValue + currentBin*interval;
maxValue = minValue + interval;
interval /= bins;
}
}
int total = src[i].total();
int p1 = 0, p2 = bins - 1;
int n1 = 0, n2 = total;
float minValue = inputMin - 0.5f;
float maxValue = inputMax + 0.5f;
float interval = (maxValue - minValue) / float(bins);
for (int j = 0; j < depth; ++j)
// searching for s1 and s2
{
while (n1 + hist[p1] < s1 * total / 100.0f)
{
n1 += hist[p1++];
minValue += interval;
}
p1 *= bins;
while (n2 - hist[p2] > (100.0f - s2) * total / 100.0f)
{
n2 -= hist[p2--];
maxValue -= interval;
}
p2 = p2*bins - 1;
interval /= bins;
}
src[i] = (outputMax - outputMin) * (src[i] - minValue)
/ (maxValue - minValue) + outputMin;
}
/****************************************************************/
break;
}
default:
CV_Assert( false );
}
dst.create(/**/ src[0].size(), CV_MAKETYPE( src[0].depth(), src.size() ) /**/);
cv::merge(src, dst);
}
/*!
* Wrappers over different white balance algorithm
*
* \param src : source image (RGB)
* \param dst : destination image
*
* \param inputMin : minimum input value
* \param inputMax : maximum input value
* \param outputMin : minimum output value
* \param outputMax : maximum output value
*
* \param algorithmType : type of the algorithm to use
*/
void balanceWhite(const Mat &src, Mat &dst, const int algorithmType,
const float inputMin, const float inputMax,
const float outputMin, const float outputMax)
{
switch ( src.depth() )
{
case CV_8U:
{
std::vector < Mat_<uchar> > mv;
split(src, mv);
balanceWhite(mv, dst, inputMin, inputMax, outputMin, outputMax, algorithmType);
break;
}
case CV_16S:
{
std::vector < Mat_<short> > mv;
split(src, mv);
balanceWhite(mv, dst, inputMin, inputMax, outputMin, outputMax, algorithmType);
break;
}
case CV_32S:
{
std::vector < Mat_<int> > mv;
split(src, mv);
balanceWhite(mv, dst, inputMin, inputMax, outputMin, outputMax, algorithmType);
break;
}
case CV_32F:
{
std::vector < Mat_<float> > mv;
split(src, mv);
balanceWhite(mv, dst, inputMin, inputMax, outputMin, outputMax, algorithmType);
break;
}
default:
CV_Assert( false );
break;
}
}
}
\ No newline at end of file
#include "test_precomp.hpp"
namespace cvtest
{
TEST(colorbalance_SimpleColorBalance, regression)
{
cv::String dir = cvtest::TS::ptr()->get_data_path();
int nTests = 12;
float threshold = 0.005;
for (int i = 0; i < nTests; ++i)
{
cv::String srcName = dir + cv::format( "sources/%02d.png", i + 1);
cv::Mat src = cv::imread( srcName, 1 );
cv::String previousResultName = dir + cv::format( "results/%02d.png", i + 1 );
cv::Mat previousResult = cv::imread( previousResultName, 1 );
cv::Mat currentResult;
cv::balanceWhite(src, currentResult, cv::WHITE_BALANCE_SIMPLE);
cv::Mat sqrError = ( currentResult - previousResult )
.mul( currentResult - previousResult );
cv::Scalar mse = cv::sum(sqrError) / cv::Scalar::all( sqrError.total()*sqrError.channels() );
EXPECT_LE( mse[0]+mse[1]+mse[2]+mse[3], threshold );
}
}
}
\ No newline at end of file
#include "test_precomp.hpp"
CV_TEST_MAIN("colorbalance")
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wextra"
# endif
#endif
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgproc/types_c.h"
#include "opencv2/highgui.hpp"
#include "opencv2/colorbalance.hpp"
#include "opencv2/ts.hpp"
#include <iostream>
#endif
This diff is collapsed.
......@@ -5,4 +5,4 @@ ximpgroc. Advanced edge-detection algorithms
.. toctree::
:maxdepth: 2
Structured forests for fast edge detection <structured_edge_detection/index>
Structured forests for fast edge detection <ximpgroc/structured_edge_detection>
......@@ -3,7 +3,8 @@ Structured forests for fast edge detection
.. highlight:: cpp
...
This module contains implementations of modern structured edge detection algorithms,
i.e. algorithms which somehow takes into account pixel affinities in natural images.
StructuredEdgeDetection
-----------------------
......@@ -40,12 +41,12 @@ StructuredEdgeDetection::detectEdges
++++++++++++++++++++++++++++++++++++
.. ocv:function:: void detectEdges(const Mat src, Mat dst)
The function detects edges in src and draw them to dst. The algorithm underlies this function
is much more robust to texture presence, than common approaches, e.g. Sobel
The function detects edges in src and draw them to dst. The algorithm underlies this function
is much more robust to texture presence, than common approaches, e.g. Sobel
:param src : source image (RGB, float, in [0;1]) to detect edges
:param dst : destination image (grayscale, float, in [0;1])
where edges are drawn
:param src: source image (RGB, float, in [0;1]) to detect edges
:param dst: destination image (grayscale, float, in [0;1])
where edges are drawn
.. seealso::
......@@ -56,15 +57,11 @@ createStructuredEdgeDetection
+++++++++++++++++++++++++++++
.. ocv:function:: Ptr<cv::StructuredEdgeDetection> createStructuredEdgeDetection(String model)
The only available constructor
The only available constructor
:param model: model file name
Literature
----------
.. [Dollar2013] Dollár P., Zitnick C. L., "Structured forests for fast edge detection",
IEEE International Conference on Computer Vision (ICCV), 2013,
pp. 1841-1848. `DOI <http://dx.doi.org/10.1109/ICCV.2013.231>`_
......@@ -6,8 +6,6 @@
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc/types_c.h"
#include <iostream>
const char* keys =
{
"{i || input image name}"
......@@ -47,7 +45,6 @@ int main( int argc, const char** argv )
return -1;
}
cv::cvtColor(image, image, CV_BGR2RGB);
image.convertTo(image, cv::DataType<float>::type, 1/255.0);
cv::Mat edges(image.size(), image.type());
......
......@@ -88,7 +88,7 @@ static cv::Mat imsmooth(const cv::Mat &src, const int rad)
return src;
else
{
const float p = 12/rad/(rad + 2) - 2;
const float p = 12.0f/rad/(rad + 2) - 2;
cv::Mat dst;
if (rad <= 1)
......@@ -98,7 +98,7 @@ static cv::Mat imsmooth(const cv::Mat &src, const int rad)
}
else
{
float nrml = CV_SQR(rad + 1);
float nrml = CV_SQR(rad + 1.0f);
std::vector <float> kernelXY(2*rad + 1);
for (int i = 0; i <= rad; ++i)
......@@ -164,7 +164,7 @@ static cv::Mat rgb2luv(const cv::Mat &src)
const float xyz[] = {mX[0]*rgb[0] + mX[1]*rgb[1] + mX[2]*rgb[2],
mY[0]*rgb[0] + mY[1]*rgb[1] + mY[2]*rgb[2],
mZ[0]*rgb[0] + mZ[1]*rgb[1] + mZ[2]*rgb[2]};
const float nz = 1.0f/(xyz[0] + 15*xyz[1] + 3*xyz[2] + 1e-35);
const float nz = 1.0f / float(xyz[0] + 15*xyz[1] + 3*xyz[2] + 1e-35);
const float l = pDst[j] = lTable[cvFloor(1024*xyz[1])];
......@@ -217,7 +217,7 @@ static void gradientHist(const cv::Mat &src, cv::Mat &magnitude, cv::Mat &histog
for (int j = 0; j < src.cols*nchannels; j += nchannels)
{
float fMagn = -1e-5, fdx, fdy;
float fMagn = float(-1e-5), fdx, fdy;
for (int k = 0; k < nchannels; ++k)
{
float cMagn = CV_SQR( pDx[j + k] ) + CV_SQR( pDy[j + k] );
......@@ -534,7 +534,7 @@ protected:
// half of cell
std::vector <int> gridPositions;
for(int i = 0; i < gridSize; i++)
gridPositions.push_back( (i+1)*(pSize/shrink + 2*hc - 1)/(gridSize + 1.0) - hc + 0.5 );
gridPositions.push_back( int( (i+1)*(pSize/shrink + 2*hc - 1)/(gridSize + 1.0) - hc + 0.5f ) );
for (int i = 0, n = 0; i < CV_SQR(gridSize)*nchannels; ++i)
for (int j = (i%CV_SQR(gridSize)) + 1; j < CV_SQR(gridSize); ++j, ++n)
......@@ -623,7 +623,7 @@ protected:
}
}
cv::reduce( dstM.reshape(1, dstM.total() ), dstM, 2, CV_REDUCE_SUM);
cv::reduce( dstM.reshape(1, int( dstM.total() ) ), dstM, 2, CV_REDUCE_SUM);
imsmooth( dstM.reshape(1, dst.rows), 1 ).copyTo(dst);
}
......
......@@ -5,9 +5,9 @@ namespace cvtest
TEST(ximpgroc_StructuredEdgeDetection, regression)
{
cv::String dir = "C:/Users/Yury/Projects/opencv/sources/opencv_contrib/modules/ximpgroc/testdata/";//cvtest::TS::ptr()->get_data_path();
cv::String dir = cvtest::TS::ptr()->get_data_path();
int nTests = 12;
float threshold = 0.01;
float threshold = 0.01f;
cv::String modelName = dir + "model.yml.gz";
cv::Ptr<cv::StructuredEdgeDetection> pDollar =
......@@ -22,7 +22,6 @@ TEST(ximpgroc_StructuredEdgeDetection, regression)
cv::Mat previousResult = cv::imread( previousResultName, 0 );
previousResult.convertTo( previousResult, cv::DataType<float>::type, 1/255.0 );
cv::cvtColor( src, src, CV_BGR2RGB );
src.convertTo( src, cv::DataType<float>::type, 1/255.0 );
cv::Mat currentResult( src.size(), src.type() );
......@@ -30,7 +29,7 @@ TEST(ximpgroc_StructuredEdgeDetection, regression)
cv::Mat sqrError = ( currentResult - previousResult )
.mul( currentResult - previousResult );
cv::Scalar mse = cv::sum(sqrError) / cv::Scalar::all( sqrError.total() );
cv::Scalar mse = cv::sum(sqrError) / cv::Scalar::all( double( sqrError.total() ) );
EXPECT_LE( mse[0], threshold );
}
......
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