White gaussian noise addition using Qt - c++

I looked out in the internet as well as I looked in here (stackoverflow) and could not find a good answer on how to implement white gaussian noise addition into my qimage object. or if there is an existing function which I can use?
any suggestions?
Thx in advance

The following code helped me alot:
#include <stdlib.h>
#include <math.h>
#include <time.h>
float gauss_rand(float mean,float stdev)
{
int i;
const int ORDER=2*12; /* 12,24,36 etc. due to del^2/12 */
const double dev_norm=1.4142136; /* sqrt(ORDER/12) */
double rndno;
rndno=-(ORDER>>1);
for(i=0;i<ORDER;i++) {
rndno+=(double)(rand()/(RAND_MAX+1.0));
}
rndno*=stdev/dev_norm;
rndno+=mean;
return((float)rndno);
}
void add_gaussian_noise(float **orig,int Ni,int Nj,float **noisy,float mean,float stdev)
{
int i,j;
static int kilroy=0;
unsigned int seed;
if(!kilroy) {
kilroy=1;
seed=(unsigned)time( NULL );
// uncomment for the same noise process
// seed=0;
srand(seed);
}
for(i=0;i<Ni;i++)
for(j=0;j<Nj;j++)
noisy[i][j]=orig[i][j]+gauss_rand(mean,stdev);
}

Related

Why the rendered squares duplicate?

My problem is that when i run programm it runs normally for around 10-20 seconds, and then it glitch out. You can see further what's happening on the video.
https://youtu.be/YOlhjQFTzZc
This error is hunting me for over a month, First i thought this was some mistake in making shorter Render function. But not.
You can see it here.
void Render(char * image_place, int object_x, int object_y)
{
SDL_Surface * object_image = IMG_Load(image_place);
SDL_Rect object_position;
object_position.x=object_x;
object_position.y=object_y;
SDL_BlitSurface(object_image, NULL, ekran, &object_position);
}
But when i started "researching" on this topic more, i discovered that it happen even without using this function!
Here is code from the video:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2/SDL_ttf.h>
#include <windows.h>
#include <time.h>
using namespace std;
//SDL
SDL_Window * okno;
SDL_Surface * ekran;
SDL_Rect pozycja_obramowki;
SDL_Event zdarzenie;
SDL_Rect tlo_pos;
//zmienne
int x_obraz=0;
int y_obraz=0;
int main(int argc, char*args[])
{
SDL_Init(SDL_INIT_EVERYTHING);
okno = SDL_CreateWindow("LevelEditor",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED, 1280, 720, NULL);
ekran = SDL_GetWindowSurface(okno);
while(true)
{
{//render
SDL_Surface * tlo = IMG_Load("biel.png");
tlo_pos.x=0;
tlo_pos.y=0;
SDL_BlitSurface(tlo,NULL, ekran, &tlo_pos);
SDL_Surface * obramowka = IMG_Load("obramowka.png");
pozycja_obramowki.x=x_obraz;
pozycja_obramowki.y=y_obraz;
SDL_BlitSurface(obramowka,NULL, ekran, &pozycja_obramowki);
}
{//zdarzenia
if(SDL_PollEvent(&zdarzenie))
{
if(zdarzenie.type==SDL_QUIT)
{
return 0;
}
}
}
{//sterowanie
if(GetAsyncKeyState(VK_RIGHT)) {x_obraz=x_obraz+5;}
if(GetAsyncKeyState(VK_LEFT)) {x_obraz=x_obraz-5;}
if(GetAsyncKeyState(VK_UP)) {y_obraz=y_obraz-5;}
if(GetAsyncKeyState(VK_DOWN)) {y_obraz=y_obraz+5;}
}
{//fps end & odswiezanie ekranu
SDL_UpdateWindowSurface(okno);
}
}
}
If i wrote something wrong or explained anything wrong, feel free to comment on this post. Any help will be useful, thanks ; )
You shouldn't call IMG_Load repeatedly. (I suspect that you're running out of memory pretty quickly.)
Load all images at startup and store pointers to the resulting surfaces.
// Moved out of the loop
SDL_Surface * tlo = IMG_Load("biel.png");
SDL_Surface * obramowka = IMG_Load("obramowka.png");
while(true)
{
// As before, but without declaring the variables mentioned above.
}

Why is my class variable changing its value between methods?

I am trying to load a bitmap animation to the screen. I have a float variable holdTime that is specified to hold the "holdtime" value for the animation. In my constructor I set the holdtimevariable to 0.1f but when I try to access the method in the class that is using the holdTime variable, the value of holdTime has changed to -107374176f. So somewhere between my constructor call and the method call the value has changed from 0.1f to -107374176f.
To make things a little bit more clearer let me show you some code:
Here is the header file for the Game class, this is where I call the constructor of the Animation class that has the holdTime variable.
#pragma once
#include "Graphics.h"
#include "Surface.h"
#include "Animation.h"
#include "FrameTimer.h"
class Game
{
public:
Game( class MainWindow& wnd );
void Go();
private:
void UpdateModel();
private:
MainWindow& wnd;
FrameTimer ft;
Surface surf = Surface("Test32x48.bmp");
Animation testAnimation = Animation(0, 0, 32, 48, 4, surf, 0.1f);
};
You see that I have this testAnimation at the bottom of the class. The last argument in the constructor call is the value that is ought be in holdTime.
This is how my Animation header file looks like:
#include "Surface.h"
#include "Graphics.h"
#include <vector>
class Animation {
public:
Animation(int x, int y, int width, int height, int count, const Surface& sprite, float holdtime, Color chroma = Colors::Magenta);
void Update(float dt);
private:
void Advance();
private:
std::vector<RectI> frames;
int iCurFrame = 0;
float holdTime = 0;
float curFrameTime = 0.0f;
};
And this is the Animation Cpp file:
#include "Animation.h"
Animation::Animation(int x, int y, int width, int height, int count,
const Surface& sprite, float holdtime, Color chroma)
:
sprite(sprite),
holdTime(holdTime),
chroma(chroma)
{
for (int i = 0; i < count; i++)
{
frames.emplace_back(x + i * width, x + (i + 1) * width,y, y + height);
}
}
void Animation::Update(float dt)
{
curFrameTime += dt;
while(curFrameTime >= holdTime) {
Advance();
curFrameTime -= holdTime;
}
}
void Animation::Advance()
{
if (++iCurFrame >= frames.size()) {
iCurFrame = 0;
}
}
There is only one method that is making use of holdTime and that is the method Update(float dt).
If we go back to the Game class and look at the Game.cpp file:
#include "MainWindow.h"
#include "Game.h"
Game::Game( MainWindow& wnd )
:
wnd( wnd ),
gfx( wnd )
{
}
void Game::Go()
{
UpdateModel();
}
void Game::UpdateModel()
{
testAnimation.Update(ft.Mark());
}
In the Method Go() we call the method UpdateModel() which in turn is calling the Update() method in the animation class. This means that the first method to be executed in the Animation class after the constructor call is the update() method. When I debug the program I can see that the value of holdtime has changed between the constructor call and the Update() method call. But I don't know how since it I am not modifying the value somewhere else. It also seemes that the new value of holdTime is garbage value.
It became a lot of code in this question and it looks a bit messy and even though I lack the skills of writing a good Title I hope I made you somewhat clear what my problem is.
Thanks!
Update:
Here is the code for the FrameTimer class since the value returned from one of its methods is passed in into the Update() method:
FrameTimer.H:
#pragma once
#include <chrono>
class FrameTimer
{
public:
FrameTimer();
float Mark();
private:
std::chrono::steady_clock::time_point last;
};
FrameTimer.cpp:
#include "FrameTimer.h"
using namespace std::chrono;
FrameTimer::FrameTimer()
{
last = steady_clock::now();
}
float FrameTimer::Mark()
{
const auto old = last;
last = steady_clock::now();
const duration<float> frameTime = last - old;
return frameTime.count();
}
Edit:
main.cpp:
int WINAPI wWinMain( HINSTANCE hInst,HINSTANCE,LPWSTR pArgs,INT )
{
MainWindow wnd( hInst,pArgs );
Game game( wnd );
while( wnd.ProcessMessage() )
{
game.Go();
}
}
As you can see the game.Go() method is the first method that is called in main.
Your Animation constructor is at fault:
Animation::Animation(int x, int y, int width, int height, int count,
const Surface& sprite, float holdtime, Color chroma)
:
sprite(sprite),
holdTime(holdTime),
chroma(chroma)
{
for (int i = 0; i < count; i++)
{
frames.emplace_back(x + i * width, x + (i + 1) * width,y, y + height);
}
}
Here you attempt to initialise the member holdTime from the parameter holdTime.
Except, there is no parameter holdTime. There is only the parameter holdtime.
Hence instead you are actually initialising the member holdTime from itself (the next nearest "match" for that name), so it only retains its original, unspecified value (and in fact, reading an uninitialised variable results in your program having undefined behaviour).
So, you see, your member variable doesn't "change" at all — you never set it correctly. You'd have known that had you put some diagnostic output inside that constructor to examine the value and see whether it's what you thought it should be. None of the rest of the code was relevant or necessary.
A properly-configured compiler should have warned you about this.

Why PCL Conditional filter return the same point cloud?

I'm working with PCL to process a point cloud in a way to end with detecting objects in the scene.
I add a custom PiontT type and it work fine with me. However, I'm struggling with the filtering algorithms in the PCL library. I tried statistical, radius, and conditional outliers removal to remove noise. The statistical did not return the results (it seems to me as if it in an infinite loop), the radius on the other hand return a cloud with size 0. and the conditional actually return the same cloud without removing any point. in both radius and statistical, I follow the example as it given but they did not work.
For now, I think the conditional removal is the most proper algorithm for me, because I want to remove any points with confidence not in the range between [0.4 - 1] . As I mentioned before that I'm using a custom point type. below is the code for the point Type (Tango3DPoitType) and the method that use conditional removal.
Tango3DPoitType.h
#define PCL_NO_PRECOMPILE
#include <pcl/point_types.h>
#include <pcl/impl/point_types.hpp>
#include <pcl/point_cloud.h>
#include <pcl/impl/instantiate.hpp>
// Preserve API for PCL users < 1.4
#include <pcl/common/distances.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/kdtree/impl/kdtree_flann.hpp>
#include <pcl/search/organized.h>
#include <pcl/search/impl/organized.hpp>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/filters/impl/statistical_outlier_removal.hpp>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/impl/radius_outlier_removal.hpp>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/impl/voxel_grid.hpp>
#include <pcl/filters/voxel_grid_covariance.h>
#include <pcl/filters/impl/voxel_grid_covariance.hpp>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/impl/extract_indices.hpp>
#include <pcl/filters/conditional_removal.h>
#include <pcl/filters/impl/conditional_removal.hpp>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/impl/sac_segmentation.hpp>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/segmentation/impl/extract_clusters.hpp>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
struct EIGEN_ALIGN16 _Tango3DPoitType
{
PCL_ADD_POINT4D; // This adds the members x,y,z which can also be accessed using the point (which is float[4])
union
{
union
{
struct
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
}; float rgb;
}; uint32_t rgba;
};
float Confidence;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW };
struct EIGEN_ALIGN16 Tango3DPoitType : public _Tango3DPoitType
{
inline Tango3DPoitType ()
{
x = y = z = 0.0f;
data[3] = 1.0f;
r = b = a = 0;
g = 255;
Confidence = 0.0f;
}
inline Tango3DPoitType (float _Confidence)
{
x = y = z = 0.0f;
data[3] = 1.0f;
r = b = a = 0;
g = 255;
Confidence = _Confidence;
}
inline Tango3DPoitType (uint8_t _r, uint8_t _g, uint8_t _b)
{
x = y = z = 0.0f;
data[3] = 1.0f;
r = _r;
g = _g;
b = _b;
a = 0;
Confidence = 0;
}
inline Eigen::Vector3i getRGBVector3i () { return (Eigen::Vector3i (r, g, b)); }
inline const Eigen::Vector3i getRGBVector3i () const { return (Eigen::Vector3i (r, g, b)); }
inline Eigen::Vector4i getRGBVector4i () { return (Eigen::Vector4i (r, g, b, 0)); }
inline const Eigen::Vector4i getRGBVector4i () const { return (Eigen::Vector4i (r, g, b, 0)); }
EIGEN_MAKE_ALIGNED_OPERATOR_NEW };
// Adding confidence as fourth data to XYZ
POINT_CLOUD_REGISTER_POINT_STRUCT (Tango3DPoitType,
(float, x, x)
(float, y, y)
(float, z, z)
(uint32_t, rgba, rgba)
(float, Confidence, Confidence)
)
POINT_CLOUD_REGISTER_POINT_WRAPPER(Tango3DPoitType, _Tango3DPoitType)
Conditional Removal Method
void CloudDenoising(const pcl::PointCloud<Tango3DPoitType>::Ptr source,
const pcl::PointCloud<Tango3DPoitType>::Ptr target){
// build the condition
pcl::ConditionAnd<Tango3DPoitType>::Ptr ConfidenceRangeCondition (new pcl::ConditionAnd<Tango3DPoitType> ());
ConfidenceRangeCondition->addComparison (pcl::FieldComparison<Tango3DPoitType>::ConstPtr (new pcl::FieldComparison<Tango3DPoitType> ("Confidence", pcl::ComparisonOps::GT, 0.5)));
ConfidenceRangeCondition->addComparison (pcl::FieldComparison<Tango3DPoitType>::ConstPtr (new pcl::FieldComparison<Tango3DPoitType> ("Confidence", pcl::ComparisonOps::LT, 1.1)));
// build the filter
pcl::ConditionalRemoval<Tango3DPoitType> conditionalRemoval;
conditionalRemoval.setCondition (ConfidenceRangeCondition);
conditionalRemoval.setInputCloud (source);
conditionalRemoval.setKeepOrganized(true);
// apply filter
conditionalRemoval.filter (*target);
}
I want to understand is I'm doing something wrong with the point type or is it a bug in PCL library.
Thank you
You are cropping the cloud but it still leting organized.
To solve it, just remove the method .setKeepOrganized(true).

vector, sfml and "the value of esp was not properly saved across the function call" error

I have a struct "Layer" and class "LayerHandler". Layer consists only a texture, sprite and two constructors - one default and one with a reference parameter. LayerHandler class is a class that handles the drawing of all the layers we have. I add layers to this class and later I use win.draw(layerhandler_object) to draw everything. LayerHandler inherits from Drawable to do so and it overrides virtual void draw().
LayerHandler.h:
#ifndef LAYERHANDLER_H
#define LAYERHANDLER_H
#include <vector>
#include <SFML\Graphics.hpp>
using namespace std;
using namespace sf;
struct Layer {
Texture tex;
Sprite spr;
Layer() { }
Layer(Layer& l) {
tex = l.tex;
spr = l.spr;
}
};
class LayerHandler : public Drawable {
private:
vector<Layer*> layers;
virtual void draw(RenderTarget& target, RenderStates states) const {
for (int i=0; i<layers.size(); i++)
target.draw(layers[i]->spr, states);
}
public:
LayerHandler();
~LayerHandler();
void Add(Layer& layer);
};
#endif
LayerHandler.cpp:
#include "LayerHandler.h"
LayerHandler::LayerHandler() {
}
LayerHandler::~LayerHandler() {
}
void LayerHandler::Add(Layer& layer) {
layers.push_back(new Layer(layer));
}
and main.cpp:
#include <iostream>
#include <SFML\Graphics.hpp>
#include "LayerHandler.h"
using namespace std;
using namespace sf;
int main() {
RenderWindow win(VideoMode(800, 600), "Raven", Style::Default);
win.setFramerateLimit(60);
win.setVerticalSyncEnabled(true);
win.setMouseCursorVisible(false);
LayerHandler lhandler;
Layer back;
back.tex.loadFromFile("bao/gfx/back.png");
back.spr.setTexture(back.tex);
back.spr.setPosition(0, 50);
lhandler.Add(back);
Event evt;
float dt = 0.f;
Clock clock;
float dwticks = clock.getElapsedTime().asMilliseconds();
float dwnewticks = 0.f;
while (win.isOpen()) {
if (win.pollEvent(evt)) {
if (Keyboard::isKeyPressed(Keyboard::Key::Escape)) {
win.close();
}
} else {
dwnewticks = clock.getElapsedTime().asMilliseconds();
dt = dwnewticks > dwticks ? (dwnewticks - dwticks) / 4000.f : 0.f;
dwticks = dwnewticks;
win.clear();
win.draw(lhandler);
win.display();
}
}
return 0;
}
I think it's not complicated and that I did everything ok, but I get this "The value of ESP was not properly saved across the function call" error. I have no idea why I get this error. I know that it may be caused by mismatched calling conventions, but I don't see anything like that in my code... I've got to say that this is the first time ever I got this error and I'm completely out of ideas how to deal with it. Any help?
Don't know why, but the problem was with SFML libraries. Here I'm using version 2.2 for 32-bit apps. I downloaded version 2.3 32-bit and compiled my app with the new 2.3 libraries and now it works perfect.

Mean shift implementation in C++

Can anyone recommend a lightweight mean shift clustering implementation in C++? I am already using OpenCV, however their mean shift implementation is for tracking, not clustering. I have seen EDISON, however, this is for image segmentation and not clustering.
I could implement it myself, however would rather not invest the time, and not take the risk of bugs.
Thanks
This is old, but I am working with mean shift right now so I thought it best to answer.
I think I understand the distinction you are making here, but when you say you are looking for mode detection this is vague in the technical sense as from the point of view of the algorithm as the algorithm inherently is for searching for "modes", which are the local minima or maxima depending on how you frame the optimization problem (Gradient descent or ascent).
This source, which was found on the EDISON site, claims to be a c++ implementation of the mean shift clustering algorithm, but as discussed above, clustering is the main implementation of the mode seeking behavior that all other uses of mean shift is based on, especially segmentation, so you can certainly use the EDISON source to find a clustering implementation, even if you have to search through it a bit.
I also found this Github project, for what it is worth, but I haven't worked with it before.
LAST NOTE: I also noticed you said "lightweight" implementation. Note that mean shift is not a very efficient algorithm (i think it is something like O(N^3), but I will check that). That said, it can still be efficiently implemented, though how that should be gauged is more ambiguous. Needless to say, Quick Shift, an attempt by UCLA researchers to solve the issues of the more efficient medoid shift, a similar non-parametric mode seeking algorithm, might be more like what you are looking for in a "lightweight" algorithm.
Here is my C++ version of mean shift object tracking method. To run the code successfully, you need to add the tf.h header file to the main code directory.
#include "tf.h" // include the header file
using namespace cv;
using namespace std;
#include <stdio.h>
makerect mkr; // rectangle for encompassing target
// rcs for row coordination of target window center
//ccs for column coordination of target window center
double rcs=0,ccs=0;
// w for width of target window
// l for length of target window
double W=70,L=60;
const int mySizes[3]={16,16,16}; // vector for number of histogram bins
cv::Mat q4hsv = Mat::zeros(3,mySizes,CV_64F); // initializing histogram variable
uchar nbins=16; // var for num of histogram bins
int main(void){
printf("enter 14 or 36: \t"); // enter number of input video name
uint flag; // var for video flag or number
cin>>flag;
Mat ref4frame; // reference frame which is used for initializing mean shift parameters
char filename [50];
sprintf(filename,"im%d.avi",flag);
VideoCapture capture(filename);
if( !capture.isOpened() )
throw "Error when reading steam_avi";
unsigned long int f4counter=0; // frame counter var
histhsv hsv; // instantiating histhsv class
for (f4counter=1;f4counter<=40000000;f4counter++){ // a big number to support many frames
capture >> ref4frame; //reading input image from specified directory
if( !(ref4frame.data )) // checking the read status
{
printf("Cannot load file image %s\n", filename);
break; }
uchar ndiv = uchar(256/nbins); // division value to which intesity values are divided
if (f4counter==1) { // special for 1st frame
char modelname[20];
if(flag==36){
sprintf(modelname,"data%d.png",flag);
}
else if (flag==14){
sprintf(modelname,"data%d.jpg",flag);
}
// imread is defined in tf.h
Mat img = imread(modelname,1);//reads 1st image
if( !(img.data ))//check if file loading is ok
{
printf("Cannot load file image %s\n", modelname);
break; }
hsv.img=img;//assign new image to hsv object (calculates hsv or rgb hist)
hsv.run();//run the histogram calculator
// assign temporary hsv object to reference hist q4hsv object
for (int i=0;i<16;i++){
for(int j=0;j<16;j++){
for(int k=0;k<16;k++){
q4hsv.at<double>(i,j,k)=hsv.q[i][j][k];
}
}
}
}
if(f4counter<5){averageglobalhsv(ref4frame,q4hsv,rcs,ccs);}
averagelocalhsv(ref4frame,q4hsv,rcs,ccs);//normalizing histogram values (0-1)
Point pt1; pt1.x=ccs; pt1.y=rcs;
int thickness=4;//thickness of marker - here is a circle
int lineType=8;
int shift=0;
RNG rng(0xFFFFFFFF);
cv::circle(ref4frame, pt1, 5, randomColor(rng), thickness, lineType,
shift); //marking object center with a circle
myimshow("reference frame",ref4frame);//show current image
waitKey(1);
}
int c=waitKey(0);
//release memory
ref4frame.release();
destroyAllWindows();
return 0;
}
here is the tf.h header file contents:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2\opencv.hpp"
#include "core\core.hpp"
#include <cstdio>
#include <iostream>
#include <fstream>
#include <math.h>
using namespace cv;
using namespace std;
// makerect class: to create the desired size encompassing window
class makerect
{
public:
double rcs,ccs,w,l; // ctl row, ctl column, width, length
uint rmin,rmax,cmin,cmax,height,length;//min max coordination vars
void run(void);
makerect();
};
makerect::makerect(){
rmin=0;rmax=0;cmin=0;cmax=0;rcs=0;ccs=0;w=0;l=0;
}
void makerect::run(){
//not that all points must be either integer or floating point
rmin=uint(rcs-floor(w/2));//min row coordination
rmax=uint(rmin+w);//max row coordination
cmin=uint (ccs-floor(l/2));//min column coordination
cmax=uint(cmin+l);//max column coordination
if(cmax>length){cmax=length;cmin=cmax-l;// checking column to be inside image}
if(rmax>height){rmax=height;rmin=rmax-w;//checking row to be inside image}
}
static Scalar randomColor(RNG& rng)
{
int icolor = (unsigned)rng;
return Scalar(icolor&255, (icolor>>8)&255, (icolor>>16)&255);
}
//myimshow: is a function to to show image
void myimshow(char* name4window,Mat &tmp4image){
namedWindow(name4window,1); imshow(name4window,tmp4image);
}
void averageglobalhsv(Mat ref4frame,Mat &f,double &rcs,double &ccs)
{
Mat img;
cvtColor(ref4frame,img,CV_BGR2HSV);//rgb2hsv conversion
uint n4rowsref=ref4frame.rows;// num of rows
uint n4colsref=ref4frame.cols;// num of cols
double *im4bp = new double [n4rowsref*n4colsref];//1-D dynamic array equal to image pixels
uint nbins=16;// num of histogram bins
uint ndiv=256/nbins; //division value to which intensities are divided
//vars for image moments (zero to second moments)
double m00=0,m01=0,m10=0,m20=0,m02=0,m11=0,w=0;
uint R=0,G=0,B=0; //red bin num, green bin num, blue bin num
for(uint i=0;i<n4rowsref;i++){ //loop through all image rows
for(uint j=0;j<n4colsref;j++){//loop through all image columns
Vec3b inten=img.at<Vec3b>(i,j);//a vector of three element
R=inten.val[2]; G=inten.val[1]; B=inten.val[0];
R/=ndiv; G/=ndiv; B/=ndiv;//calculating the bin to which current pixel intensity belong
im4bp[i*n4colsref+j]=1.3*sqrt(f.at<double>(R,G,B));//calculating spatial weighted kernel histogram formula
}
}
for(uint i=0;i<n4rowsref;i++){//loop through all image rows
for(uint j=0;j<n4colsref;j++){//loop through all image columns
w=im4bp[j+n4colsref*i];// weight for pixel at (i,j)
m01=m01+double(i)*w;//first moment on y/row coordination
m10=m10+double(j)*w;//first moment on x/column coordination
m00=m00+w;//zeroth moment which is sum of all moments
}
}
if(m00>0){
rcs=ceil(m01/m00);//central point for row
ccs=ceil(m10/m00);}//central point for column
delete im4bp;//cleaning memory
}
void averagelocalhsv(Mat ref4frame,Mat &f,double &rcs,double &ccs)
{
Mat img;
cvtColor(ref4frame,img,CV_BGR2HSV);
makerect mkr;
int sz[]={2,2};
uint n4rowsref=ref4frame.rows;
uint n4colsref=ref4frame.cols;
double *im4bp = new double [n4rowsref*n4colsref];
uint nbins=16;
uint ndiv=256/nbins;
double m00=0,m01=0,m10=0,m20=0,m02=0,m11=0,w=0,Dxx,Dyy,Dxy;
uint R=0,G=0,B=0;
for(uint i=0;i<n4rowsref;i++){
for(uint j=0;j<n4colsref;j++){
Vec3b inten=img.at<Vec3b>(i,j);
R=inten.val[2]; G=inten.val[1]; B=inten.val[0];
R/=ndiv; G/=ndiv; B/=ndiv;
im4bp[i*n4colsref+j]=1.3*sqrt(f.at<double>(R,G,B));
}
}
for(int iter=1;iter<5;iter++){
mkr.rcs=rcs;mkr.ccs=ccs;mkr.w=100;mkr.l=100;mkr.height=ref4frame.rows;
mkr.length=ref4frame.cols; mkr.run();
m00=0;m01=0;m10=0;m20=0;m02=0;m11=0;
for(uint i=mkr.rmin;i<mkr.rmax;i=i+1){
for(uint j=mkr.cmin;j<mkr.cmax;j=j+1){
w=im4bp[j+n4colsref*i];
m01=m01+double(i)*w;
m10=m10+double(j)*w;
m00=m00+w;
}
}
}
if(m00>0){
rcs=ceil(m01/m00);
ccs=ceil(m10/m00);
}
delete im4bp;
}
class histhsv{
public:
histhsv();
void run(void);
Mat img;
double q[16][16][16];
};
histhsv::histhsv(){};
void histhsv::run(void){
//Mat hsv4image;
double sum4hist=0;
uchar nbins=16;
uchar ndiv=256/nbins;
double wmax =0;;
double r_center=0;
double c_center =0;
r_center = img.rows/2;
c_center = img.cols/2;
for (int i=0;i<nbins;i++){for(int j=0;j<nbins;j++){for(int k=0;k<nbins;k++){
q[i][j][k]=0; } } };
cvtColor(img,img,CV_BGR2HSV);
int H=0,S=0,V=0;
for(int r=0;r<img.rows;r++){
for(int c=0;c<img.cols;c++){
Vec3b intensity = img.at<Vec3b>(r,c);
H=intensity.val[0]/ndiv;
S=intensity.val[1]/ndiv;
V=intensity.val[2]/ndiv;
q[H][S][V]+=wmax-(pow(r-r_center,2)+pow(c-c_center,2));
sum4hist+=q[H][S][V];
}
}
for (int i=0;i<nbins;i++){
for(int j=0;j<nbins;j++){
for(int k=0;k<nbins;k++){
q[i][j][k]/=sum4hist;
}
}
}
}