Use C++ armadillo Expectation Maximization for Gaussian mixture model - c++

I am trying to use armadillo's expectation maximization maximization gmm_diag class, but when I try to compile it I get "error gmm_diag was not declared in this scope".
My code is as follows:
#include <stdio.h>
#include <iostream>
#include <vector>
#include <armadillo>
#include <omp.h>
using namespace std;
using namespace arma;
int main()
{
// create synthetic data with 2 Gaussians
uword N = 10000;
uword d = 5;
mat data(d, N, fill::zeros);
vec mean0 = linspace<vec>(1,d,d);
vec mean1 = mean0 + 2;
uword i = 0;
while(i < N)
{
if(i < N) { data.col(i) = mean0 + randn<vec>(d); ++i; }
if(i < N) { data.col(i) = mean0 + randn<vec>(d); ++i; }
if(i < N) { data.col(i) = mean1 + randn<vec>(d); ++i; }
}
gmm_diag model;
model.learn(data, 2, maha_dist, random_subset, 10, 5, 1e-10, true);
model.means.print("means:");
double scalar_likelihood = model.log_p( data.col(0) );
rowvec set_likelihood = model.log_p( data.cols(0,9));
double overall_likelihood = model.avg_log_p(data);
uword gaus_id = model.assign( data.col(0), eucl_dist );
urowvec gaus_ids = model.assign( data.cols(0,9), prob_dist );
urowvec hist1 = model.raw_hist (data, prob_dist);
rowvec hist2 = model.norm_hist(data, eucl_dist);
model.save("my_model.gmm");
// the table is now initialized
}

Related

How to speed up my code by openmp with multi for loops

Now, l am trying to accelerate the calculation of center of mass in different ROI areas.Her is my original code:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv/cv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "omp.h"
#include <time.h>
#include <ctime>
#define File_SubAperture "SubAperture.txt"
#define Row_Subapaerture 750
Mat src;
Mat src_gray;
using namespace cv;
using namespace std;
int thresh = 0;
int max_thresh = 255;
Mat ROI;
int nn = 0;
float subApX[751] = { 0 };
float subApY[751] = { 0 };
float x = 0.0;
float y = 0.0;
float k = 0.0;
float f = 0.0;
int main()
{
clock_t startTime, endTime;
int SubAperture[Row_Subapaerture][Col_Subaperture];
double data1, data2, data3, data4;
int i;
Rect rect_subaperture[Row_Subapaerture];
FILE * fp_SubAperture;
FILE* px;
px = fopen("C:\\Users\\DELL\\Desktop\\AO acceleration\\center-coordinates-x.txt", "w+");
FILE* py;
py=fopen("C:\\Users\\DELL\\Desktop\\AO acceleration\\center-coordinates-y.txt", "w+");
//---read file Sub-aperture.txt---*
fp_SubAperture = fopen(File_SubAperture, "r");
if (fp_SubAperture == NULL)
{
perror("Couldn't open the file " File_SubAperture);
exit(1);
}
for (i = 0; fscanf(fp_SubAperture, "%lf%lf%lf%lf", &data1, &data2, &data3, &data4) != EOF; ++i)
{
SubAperture[i][0] = (int)data1;
SubAperture[i][1] = (int)data2;
SubAperture[i][2] = (int)data3;
SubAperture[i][3] = (int)data4;
}
fclose(fp_SubAperture);
//read image
float sumval = 0.0;
MatIterator_<uchar> it, end;
src = imread("WFS_29x29-circle.png", CV_LOAD_IMAGE_COLOR);
cvtColor(src, src_gray, CV_BGR2GRAY);
//imshow("gray image", src_gray);
//calculate the ROI area in advance
for (i = 0; i < 749; i++)
{
rect_subaperture[i].x = SubAperture[i][0];
rect_subaperture[i].y = SubAperture[i][1];
//rect_subaperture[i].width = SubAperture[i][2] - SubAperture[i][0];
//rect_subaperture[i].height = SubAperture[i][3] - SubAperture[i][1];
rect_subaperture[i].width = 4;
rect_subaperture[i].height = 4;
}
startTime = clock();// time start
omp_set_num_threads(2);
#pragma omp parallel private(ROI,it,i,k,f ) firstprivate(sumval,x,y) shared(src_gray,subApX,subApY,rect_subaperture)
#pragma omp for nowait schedule(guided) collapse(2)
for(i=0; i<749;i++)
{
ROI = src_gray(rect_subaperture[i]);
for (it = ROI.begin<uchar>(), end = ROI.end<uchar>(); it != end; it++)
{
((*it) > thresh) ? sumval += (*it) : NULL;
// printf("sum = %f\n", sumval);
}
for (int k = 0; k < ROI.cols; k++)
{
for (int f = 0; f < ROI.rows; f++)
{
float S = ROI.at<uchar>(f, k);
if (S < thresh)
S = 0;
x += (k * S) / sumval;
y += (f * S) / sumval;
}
}
subApX[i]= x + SubAperture[i][0];
subApY[i]= y + SubAperture[i][1];
fprintf(px, "\n%f", subApX[i]);
fprintf(py, "\n%f", subApY[i]);
}
endTime = clock();
printf("time = %f\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
return 0;
}
As you see, I must use multi for loops to finish the calculation. However, the whole code will stuck without any errors, only 50% of calculation is finished, the rest of them can't be calculated.
Anyone knows what's the problems I met? and how to speed up my code. The goal of this code is to calculate the center of mass in different ROI ares of one image. The coordinates will be saved as .TXT files and code will calculate the time needed.

Fill a symmetric matrix using an array

I am trying to create a symmetric matrix n x n matrix and fill it using a n*(n+1)/2 dimension array using the boost library in c++.
So far, I am able to create the matrix, and fill it with random values using the following code
#include <iostream>
#include <fstream>
#include </usr/include/boost/numeric/ublas/matrix.hpp>
#include </usr/include/boost/numeric/ublas/matrix_sparse.hpp>
#include </usr/include/boost/numeric/ublas/symmetric.hpp>
#include </usr/include/boost/numeric/ublas/io.hpp>
using namespace std;
int test_boost () {
using namespace boost::numeric::ublas;
symmetric_matrix<double, upper> m_sym (3, 3);
double filler[6] = {0, 1, 2, 3, 4, 5};
for (unsigned i = 0; i < m_sym.size1 (); ++ i)
for (unsigned j = i; j < m_sym.size2 (); ++ j)
m_sym (i, j) = filler[i+j*m_sym.size1()];
std::cout << m_sym << std::endl;
return 0;
}
What I am trying to do is fill the upper (or lower) part of the symmetric matrix using the values from the array filler. So the output upper symmetric matrix should be
| 0 | 1 | 2 |
------------------------------------------------
0 | 0 1 3
1 | 1 2 4
2 | 3 4 5
Any idea on how to do that?
I'd simplify this a bit by just keeping an iterator that traverses filler from start to end:
symmetric_matrix<double, upper> m_sym (3, 3);
double filler[6] = {0, 1, 2, 3, 4, 5};
assert(m_sym.size1() == m_sym.size2());
double const* in = std::begin(filler);
for (size_t i = 0; i < m_sym.size1(); ++ i)
for (size_t j = 0; j <= i && in != std::end(filler); ++ j)
m_sym (i, j) = *in++;
Prints: Live On Coliru
I'd personally suggest creating a helper function like:
Live On Wandbox
#include <iostream>
#include <fstream>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/symmetric.hpp>
#include <boost/numeric/ublas/io.hpp>
namespace bnu = boost::numeric::ublas;
template <typename T = double>
bnu::symmetric_matrix<T, bnu::upper> make_symmetric(std::initializer_list<T> filler) {
size_t n = (sqrt(8*filler.size() + 1) - 1)/2;
assert((n*(n+1))/2 == filler.size());
bnu::symmetric_matrix<T, bnu::upper> result(n, n);
auto in = std::begin(filler);
for (size_t i = 0; i < result.size1(); ++ i)
for (size_t j = 0; j <= i && in != std::end(filler); ++ j)
result (i, j) = *in++;
return result;
}
int main() {
std::cout << make_symmetric({0,1,2}) << "\n";
std::cout << make_symmetric({0,1,2,3,4,5}) << "\n";
std::cout << make_symmetric({0,1,2,3,4,5,6,7,8,9}) << "\n";
}
Prints
[2,2]((0,1),(1,2))
[3,3]((0,1,3),(1,2,4),(3,4,5))
[4,4]((0,1,3,6),(1,2,4,7),(3,4,5,8),(6,7,8,9))
Note: the size checks use the series expansion for 1 + ... + n and the inverse of that: n = 1/2 (sqrt(8 x + 1) - 1)

How to improve otsu threshold output

I am using otsu threshold on an image.
Here is the input image :
Here is the output :
Here is the code I am using:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
using namespace cv;
int main(int argc, char const *argv[]) {
title("Text Extractor");
string win_name = "textextractor";
Mat img_a;
img_a = imread("../input/test_c.jpg");
Mat img_a_gray;
cvtColor(img_a, img_a_gray, CV_BGR2GRAY);
Mat img_a_blur;
GaussianBlur(img_a_gray, img_a_blur, Size(3, 3), 0, 0);
Mat img_a_thres;
// adaptiveThreshold(img_a_blur, img_a_thres, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 5, 4);
threshold(img_a_blur, img_a_thres, 0, 255, THRESH_OTSU);
namedWindow(win_name + "_a", CV_WINDOW_AUTOSIZE);
imshow(win_name + "_a", img_a_thres);
imwrite("../output/output_a.jpg", img_a_thres);
waitKey(0);
return 0;
}
The problem is that output has a black region on the bottom and on the left. What can I do to minimize/remove this ?
Edit:
I tried equalizeHist() and I am getting this:
Will try out breaking image into pieces and working them separately.
Sorry, my bad. The previous one is using adaptive filtering. Using Otsu I get this:
There is no change in otsu's output :/
Edit 2: Completed the Feng Tan algorithm, it gives better results but text looses clarity.
Code:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/photo/photo.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
using namespace cv;
int main(int argc, char const *argv[]) {
string win_name = "textextractor";
Mat img_c;
img_c = imread("../input/sample.jpg");
Mat img_c_gray;
cvtColor(img_c, img_c_gray, CV_BGR2GRAY);
Mat img_c_bin = Mat::zeros(img_c_gray.rows, img_c_gray.cols, CV_8UC1);
int s_win = 17;
int l_win = 35;
double min_tau = 10;
Rect roi_s = Rect(-s_win/2, -s_win/2, s_win, s_win);
Rect roi_l = Rect(-l_win/2, -l_win/2, l_win, l_win);
Rect img_c_roi = Rect(0, 0, img_c_gray.cols, img_c_gray.rows);
for (size_t r = 0; r < img_c_gray.rows; r++) {
for (size_t c = 0; c < img_c_gray.cols; c++) {
double pthres = 255;
Rect sROI = roi_s + Point(c, r);
sROI = sROI & img_c_roi;
if(sROI.width == 0 || sROI.height == 0) {
continue;
}
Rect lROI = roi_l + Point(c, r);
lROI = lROI & img_c_roi;
if(lROI.width == 0 || lROI.height == 0) {
continue;
}
Mat sROI_gray = img_c_gray(sROI);
Mat lROI_gray = img_c_gray(lROI);
double s_stdDev = 0;
double l_stdDev = 0;
double s_mean = 0;
double l_mean = 0;
double l_min = DBL_MAX;
for (size_t r = 0; r < sROI_gray.rows; r++) {
for (size_t c = 0; c < sROI_gray.cols; c++) {
s_mean += sROI_gray.at<unsigned char>(r, c);
}
}
s_mean = s_mean / static_cast<double> (sROI_gray.cols * sROI_gray.rows);
for (size_t r = 0; r < sROI_gray.rows; r++) {
for (size_t c = 0; c < sROI_gray.cols; c++) {
double diff = sROI_gray.at<unsigned char> (r, c) - s_mean;
s_stdDev += diff * diff;
}
}
s_stdDev = sqrt(s_stdDev / static_cast<int> (sROI_gray.cols * sROI_gray.rows));
for (size_t r = 0; r < lROI_gray.rows; r++) {
for (size_t c = 0; c < lROI_gray.cols; c++) {
l_mean += lROI_gray.at<unsigned char> (c, r);
if(lROI_gray.at<unsigned char> (r, c) < l_min) {
l_min = lROI_gray.at<unsigned char> (r, c);
}
}
}
l_mean = l_mean / static_cast<double> (lROI_gray.cols * lROI_gray.rows);
for (size_t r = 0; r < lROI_gray.rows; r++) {
for (size_t c = 0; c < lROI_gray.cols; c++) {
double diff = lROI_gray.at<unsigned char> (r, c) - l_mean;
l_stdDev += diff * diff;
}
}
l_stdDev = sqrt(l_stdDev / static_cast<double> (lROI_gray.cols * lROI_gray.rows));
double tau = ((s_mean - l_min) * (1 - s_stdDev / l_stdDev)) / 2.0;
if(tau < min_tau) {
tau = min_tau;
}
double threshold = s_mean - tau;
unsigned char pixel_val = img_c_gray.at<unsigned char>(r, c);
if(pixel_val >= threshold) {
img_c_bin.at<unsigned char> (r, c) = 255;
} else {
img_c_bin.at<unsigned char> (r, c) = 0;
}
}
}
namedWindow(win_name + "_c", CV_WINDOW_AUTOSIZE);
imshow(win_name + "_c", img_c_bin);
imwrite("../output/output_c.jpg", img_c_bin);
waitKey(0);
return 0;
}
Output:
This is what I was able to obtain after some trial and run. Initially I median blurred the original image. Then I applied adpative threshold to the blurred image.
This is what I got:
1. Adaptive Threshold using Gaussian filter:
2. Adaptive Threshold using Mean filter:
From here on you can carry out a series of morphological operations that best suits your final image. :)
You should try using CLAHE.
I tried it on MATLAB using:
Ia = imread('FHXTJ.jpg');
I = rgb2gray(Ia);
A = adapthisteq(I, 'clipLimit', 0.02, 'Distribution', 'rayleigh');
Result:
Note: You can apply thresholding on this image. Otsu should work fine now.

Dynamic Programming for Minimum Path Sum

I am not understanding how to exactly use dynamic programming for the Minimum Path Sum Problem. The problem statement is as follows.
Given a m x n grid filled with non-negative numbers, find a path from
top left to bottom right which minimizes the sum of all numbers
along its path.
Note: You can only move either down or right at any point in time.
Here is the code i tried using just recursion.
#include "stdafx.h"
#include "vector"
#include "iostream"
#include "cmath"
#include "algorithm"
using namespace std;
class Solution {
public:
int s = INT_MAX;
int helper(int sum, vector<vector<int>> &grid, int i, int j) {
if (i == grid.size() - 1 && j == grid[0].size() - 1) {
return s = min(s, sum + grid[i][j]);
}
if (i >= grid.size() || j >= grid[0].size()) {
return sum;
}
return min(helper(sum + grid[i][j], grid, i + 1, j) + helper(sum + grid[i][j], grid, i, j + 1), s);
}
int minPathSum(vector<vector<int>>& grid) {
return helper(0, grid, 0, 0);
}
};
int main()
{
vector<int> v = { 1,2,3 };
vector<vector<int>> r;
r.push_back(v);
v = { 4,5,6 };
r.push_back(v);
v = { 7,8,9 };
r.push_back(v);
v = { 1,2,3 };
r.push_back(v);
Solution s;
cout<<s.minPathSum(r);
return 0;
}
And here is a code where i tried using Dynamic programming where I am storing the least sum at a given index [i,j] and returning it, but its not being of much help, the Online Coding Judge says "Time Limit Exceeded"
Can you please help me improve the code.
#include "stdafx.h"
#include "vector"
#include "iostream"
#include "cmath"
#include "algorithm"
using namespace std;
class Solution {
public:
int s = INT_MAX;
int helper(int sum, vector<vector<int>> &grid, int i, int j,vector<vector<int>> &memoize) {
if (i == grid.size() - 1 && j == grid[0].size() - 1) {
return s = min(s, sum + grid[i][j]);
}
if (i >= grid.size() || j >= grid[0].size()) {
return sum;
}
if (sum + grid[i][j] < memoize[i][j])
memoize[i][j] = sum + grid[i][j];
else
return memoize[i][j];
return min(helper(sum + grid[i][j], grid, i + 1, j,memoize) + helper(sum + grid[i][j], grid, i, j + 1,memoize), s);
}
int minPathSum(vector<vector<int>>& grid) {
vector<vector<int>> memoize(grid.size(), vector<int>(grid[0].size(), INT_MAX));
return helper(0, grid, 0, 0,memoize);
}
};
int main()
{
vector<int> v = { 1,2,3 };
vector<vector<int>> r;
r.push_back(v);
v = { 4,5,6 };
r.push_back(v);
v = { 7,8,9 };
r.push_back(v);
v = { 1,2,3 };
r.push_back(v);
Solution s;
cout<<s.minPathSum(r);
return 0;
}

'std::vector<double>::iterator' has no member named 'begin'

So I am trying to perform recursion ( A very simple code for split radix recursive butterflies) on a large C++ STL vector and I am using iterators to call the recursion but it isn't working as I keep getting errors.
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
template <typename T>
class fft_data{
public:
vector<T> re;
vector<T> im;
};
void inline split_radix_rec(vector<double>::iterator r,vector<double>::iterator i, int sgn,int N) {
if (N == 1) {
return;
} else if (N == 2) {
for (int k = 0; k < N/2; k++) {
int index = 2*k;
int index1 = index+1;
double taur = *(r+index1);
double taui = *(i+index1);
*(r+index1) = *(r+index) - taur;
*(i+index1) = *(i+index) - taui;
*(r+index) = *(r+index) + taur;
*(i+index) = *(i+index) + taui;
}
N=N/2;
} else {
int m = N/2;
int p = N/4;
double PI2 = 6.28318530717958647692528676655900577;
double theta = -1.0 * sgn * PI2/N;
double S = sin(theta);
double C = cos(theta);
double PI6 = 3.0*6.28318530717958647692528676655900577;
double theta3 = -1.0 * sgn * PI6/N;
double S3 = sin(theta3);
double C3 = cos(theta3);
double wlr = 1.0;
double wli = 0.0;
//T wl2r = (T) 1.0;
//T wl2i = (T) 0.0;
double wl3r = 1.0;
double wl3i = 0.0;
double tau1r,tau1i,tau2r,tau2i;
double ur,ui,vr,vi;
for (int j = 0; j < p; j++) {
int index1 = j+m;
int index2 = index1+p;
int index3 = j+p;
tau1r = *(r+index1);
tau1i = *(i+index1);
tau2r = *(r+index2);
tau2i = *(i+index2);
ur = tau1r + tau2r;
ui = tau1i + tau2i;
vr = sgn* (tau2r - tau1r);
vi = sgn* (tau2i - tau1i);
*(r+index2) = *(r+index3) - vi;
*(i+index2) = *(i+index3) + vr;
*(r+index1) = *(r+j) - ur;
*(i+index1) = *(i+j) - ui;
*(r+index3) = *(r+index3) + vi;
*(i+index3) = *(i+index3) - vr;
*(r+j) = *(r+j) + ur;
*(i+j) = *(i+j) + ui;
}
split_radix_rec(r.begin(),i.begin(),sgn,m);
split_radix_rec(r.begin()+m,i.begin()+m,sgn,p);
split_radix_rec(r.begin()+m+p,i.begin()+m+p,sgn,p);
}
}
int main() {
vector<double> u,v;
for (int i = 0; i < 256; i++) {
u.push_back(i);
v.push_back(i);
}
int sgn = 1;
int N = 256;
split_radix_rec(u.begin(),v.begin(),sgn,N);
return 0;
}
Here are the errors I am getting
main.cpp:93:21: error: 'std::vector<double>::iterator' has no member named 'begin'
6 Identical errors on lines 93,94,95 (the three split_radix_rec() functions called from within the split_radix_rec function). This is part of a much larger code so I want it to work for STL vectors. What am I doing wrong?
As the error states, you are calling begin() on a std::vector<double>::iterator.
You should call that on a std::vector<double>, so that it could return you a std::vector<double>::iterator.
r,i are itself iterators(begins) in your code.
Try:
split_radix_rec(r,i,sgn,m);
split_radix_rec(r+m,i+m,sgn,p);
split_radix_rec(r+m+p,i+m+p,sgn,p);
There is way too much code to give you a concise answer, but the error clearly states that you are calling begin() on a vector iterator instead of a vector. And that happens at the split_radix_rec recursive call. You may have intended this instead:
split_radix_rec(r,i,sgn,m);
split_radix_rec(r+m,i+m,sgn,p);
split_radix_rec(r+m+p,i+m+p,sgn,p);