Skip to content
Snippets Groups Projects
draw.h 8.85 KiB
Newer Older
  • Learn to ignore specific revisions
  • #ifndef DRAW_H
    #define DRAW_H
    
    #include "structs.h"
    
    #include "parameter.h"
    #include "help.h"
    
    #if defined (_MSC_VER) 
    
    #pragma component(browser, off, references)
    
    #pragma warning(push, 0)
    
    #elif (__INTEL_COMPILER)
    #pragma diagnostic push
    #pragma warning ( disable : 61 )
    #elif (__GNUC__) 
    #pragma GCC diagnostic push
    
    #pragma GCC system_header
    //#pragma GCC diagnostic ignored "-Wno-multichar"
    
    #endif
    
    //#define cimg_use_png
    #include "CImg.h"
    //#include "png.h"
    
    
    #if defined (_MSC_VER) 
    
    #pragma warning(pop)
    
    #pragma component(browser, on, references)
    
    #elif (__INTEL_COMPILER)
    #pragma diagnostic pop
    #elif (__GNUC__) 
    #pragma GCC diagnostic pop
    
    #endif
    
    
    using namespace cimg_library;
    
    #undef max
    #undef min
    
    class draw
    {
    public:
    
    	static void plot_pair(result_dtw const &result, input_method const &input, input_info const &info, parameter const &params)
    
    	{
    		CImg<short> tsA;
    		CImg<short> tsB;		
    
    		auto max = std::max(calcul::vtr_max(input.A), calcul::vtr_max(input.B));
    		auto maxMean = std::max(calcul::vtr_max(calcul::vtr_mean(input.A)), calcul::vtr_max(calcul::vtr_mean(input.B)));
    
    		if (input.A[0].size() > 1) {	
    			tsA = (draw::draw_serieBars(input.A, max).append(draw::draw_serieMean(input.A, maxMean), 'y')).rotate(90);
    			tsB = draw::draw_serieBars(input.B, max).append(draw::draw_serieMean(input.B, maxMean), 'y');
    
    		else{
    			tsA = draw::draw_serie(input.A, max).rotate(90);
    			tsB = draw::draw_serie(input.B, max);
    
    		CImg<short> m2 = result.matrix_noacc;
    		m2 = m2.append(tsB, 'y');
    
    		CImg<short> all;
    		all = result.matrix_acc;
    		all = all.append(tsA);
    		all.append(m2);
    
    		all.save(generateName(info, params.drawOut).c_str());
    	}
    
    	static void plot_segmets(input_method const &input, vtr2<result_dtw> const &result, input_info const &info, parameter const &params)
    	{
    		CImg<short> matrix;
    
    		for (size_t i = 0; i < result.size(); i++)
    		{
    			CImg<short> row;
    			for (size_t j = 0; j < result[i].size(); j++)
    			{
    				row = row.append(result[i][j].matrix_noacc);
    			}
    			matrix = matrix.append(row, 'y');
    		}
    
    
    		CImg<short> serieA;
    		CImg<short> serieB;
    		auto max = std::max(calcul::vtr_max(input.A), calcul::vtr_max(input.B));
    
    
    		if (input.A[0].size() > 1)
    		{
    
    			serieA = (draw::draw_serieBars(input.A, max).append(draw::draw_serieMean(input.A, max))).rotate(90);
    			serieB = draw::draw_serieBars(input.B, max).append(draw::draw_serieMean(input.B, max), 'y');
    
    			serieA = draw::draw_serie(input.A, max).rotate(90);
    			serieB = draw::draw_serie(input.B, max);
    
    		auto all = matrix.append(serieB, 'y');
    		all = serieA.append(all);
    
    
    		all.save(generateName(info, params.drawOut).c_str());
    
    	static CImg<short> draw_combine(vtr2<node> const &matrix, vtr<result_path> const &warpings,  parameter const &params)
    
    		CImg<short> img((int)matrix[0].size() - 1, (int)matrix.size() - 1, 1, 3, 0);
    
    		
    		const float green[] = { 0, 255, 0 };
    
    		draw_matrix(img, matrix, params);
    		draw_warpings(img, warpings, green);
    
    		if (params.drawMin)
    			draw_minimums(img, matrix);
    		
    		return img;
    	}
    
    	static void draw_matrix(CImg<short> &img, vtr2<node> const &matrix, parameter const &params)
    	{
    		double max = getMax(matrix, params);
    
    		for (size_t i = 1; i < matrix.size(); i++) { //row//y
    
    			for (size_t j = 1; j < matrix[i].size(); j++) //coll//x
    
    				auto colorRGB = draw::getColor(0, max, matrix[i][j].value);
    				const float color[] = { colorRGB.r, colorRGB.g, colorRGB.b };
    
    				img.draw_point((int)j - 1, (int)i - 1, color);
    
    	static void draw_minimums(CImg<short> &img, vtr2<node> const &matrix)
    	{
    		const float red[] = { 255, 0, 0 };
    		
    		for (size_t i = 1; i < matrix.size(); i++) { //row//y
    			for (size_t j = 1; j < matrix[i].size(); j++)//coll//x
    
    				double current = matrix[i][j].value;
    
    
    				if (i + 1 < matrix.size() && j + 1 < matrix[i].size() &&
    
    					matrix[i - 1][j].value > current && matrix[i - 1][j + 1].value > current && matrix[i][j - 1].value > current &&
    					matrix[i][j + 1].value > current && matrix[i + 1][j - 1].value > current && matrix[i + 1][j].value > current) {
    
    					img.draw_point((int)j - 1, (int)i - 1, red);
    
    	static void draw_warpings(CImg<short> &img, vtr<result_path> const &warpings, const float *color)
    
    		for (size_t i = 0; i < warpings.size(); i++) 
    			for (size_t j = 0; j < warpings[i].pathCoords.size(); j++) 
    				img.draw_point(warpings[i].pathCoords[j].col - 1, warpings[i].pathCoords[j].row - 1, color);
    	}
    
    	static double getMax(vtr2<node> const &matrix, parameter const &params) 
    	{
    		int lenA = (int)matrix.size() - 1;
    		int lenB = (int)matrix[0].size() - 1;
    
    		double max = constant::MIN_double;
    
    
    		const int w = (int)(lenB * params.w);
    		double coef = lenB / static_cast<double>(lenA);
    
    		for (size_t i = 1; i < lenA + 1; i++) // Iterating over rows
    
    			const size_t start = calcul::dtw_wpassStart(i, w, coef);
    			const size_t end = calcul::dtw_wpassEnd(i, w, coef, lenB);
    			for (size_t j = start; j < end; j++)
    
    			{
    				if (matrix[i][j].value > max)
    					max = matrix[i][j].value;
    			}
    
    	static CImg<short> draw_serie(vtr2<double> const &serie, double max)
    
    		int height = (int)ceil(serie.size() * 0.1);
    		CImg<short> img((int)serie.size(), height, 1, 3, 0);
    		double mul = (height - 1) / max;
    
    
    		const float color[] = { 255, 0, 0 };
    
    		for (size_t i = 0; i < serie.size() - 1; i++)
    
    			int a = (int)(mul * serie[i][0]);
    			int b = (int)(mul * serie[i + 1][0]);		
    
    			img.draw_line((int)i, a, (int)i + 1, b, color);
    
    		}
    
    		return img.mirror('y'); 
    	}
    
    
    	static CImg<short> draw_serieBars(vtr2<double> const &series, double max)
    
    		int barSize = (int)ceil(series.size() * 0.01); 
    
    		CImg<short> img((int)series.size(), barSize * (int)series[0].size() , 1, 3, 0);
    
    				
    		size_t dims = series[0].size();
    
    		for (size_t i = 0; i < dims; i++)
    		{
    			for (size_t j = 0; j < series.size(); j++) //col x
    			{	
    
    				color mycolor = getColor(0, max, series[j][i]);
    
    				const float color[] = { mycolor.r, mycolor.g, mycolor.b };
    
    
    				img.draw_line((int)j, (int)i * barSize, (int)j, ((int)i + 1) * barSize, color);
    
    	static CImg<short> draw_serieMean(vtr2<double> const &serie, double max)
    
    		int height = (int)ceil(serie.size() * 0.1);
    		CImg<short> img((int)serie.size(), height, 1, 3, 0);
    		double mul = (height - 1) / max;		// -2 ..means are double... so they overlap with bars
    
    		auto means = calcul::vtr_mean(serie);
    		
    
    		const float color[] = { 255, 0, 0 };
    
    		for (size_t i = 0; i < serie.size() - 1; i++)
    
    			//double mean1 = 0, mean2 = 0;
    			//for (size_t j = 0; j < serie[0].size(); j++)
    			//{
    			//	mean1 += serie[i][j];
    			//	mean2 += serie[i + 1][j];
    			//}
    			//
    			//mean1 = mean1 / serie[i].size();
    			//mean2 = mean2 / serie[i + 1].size();
    
    			int y1 = (int)floor(mul * means[i]);
    			int y2 = (int)floor(mul * means[i + 1]);
    
    			img.draw_line((int)i, y1, (int)i + 1, y2, color);
    
    		}
    
    		return img.mirror('y');
    	}
    
    
    	static std::string generateName(input_info const &input, std::string path)
    
    	{
    		std::stringstream ss;
    		if (help::pathExists(path)) {
    			if (help::isFolder(path))
    				 ss << path 
    					<< "\\" 
    					<< input.nameA 
    					<< ((input.nameA == std::to_string(input.idxA)) ? "" : ("(" + std::to_string(input.idxA + 1) + ")"))
    					<< "-"
    					<< input.nameB 
    					<< ((input.nameB == std::to_string(input.idxB)) ? "" : ("(" + std::to_string(input.idxB + 1) + ")"))
    					<< ".bmp";
    			else
    				ss << path;
    		}
    		else
    		{
    			size_t nameIdx = path.find_last_of("\\/") + 1;
    			std::string nameOnly = path.substr(nameIdx, (int)path.size() - nameIdx);
    
    			size_t extIdx = nameOnly.find_last_of(".bmp") + 1;
    
    			if (extIdx != std::string::npos && nameOnly.size() - extIdx == 4)
    				ss << path;
    			else
    				ss << path << ".bmp";
    		}
    
    		return ss.str();
    	}
    
    
    	static color getColor(double min, double max, double value)
    	{
    		color c;
    		double mul = 0;
    
    		if (max != 0)
    			mul = 1275 / max;  //0-x ... x+1colors
    
    		float place = (float)(mul * value);
    
    		int under = (int)(place / 255) * 255;
    		float exact = (float)((place - under >= 1) ? place - under : 255);
    
    		if (place < 256) //blue
    		{
    			c.r = 0;
    			c.g = 0;
    			c.b = place;
    		}
    		else if (place < 2 * 256 - 1) // purlple
    		{
    			c.r = exact;
    			c.g = 0;
    			c.b = 255;
    		}
    		else if (place < 3 * 256 - 2) //red
    		{
    			c.r = 255;
    			c.g = 0;
    			c.b = 255 - exact;
    		}
    		else if (place < 4 * 256 - 3) //orange //yellow
    		{
    			c.r = 255;
    			c.g = exact;
    			c.b = 0;
    		}
    		else if (place < 5 * 256 - 4) // whiteish
    		{
    			c.r = 255;
    			c.g = 255;
    			c.b = exact;
    		}
    		else //white (hausnumeros)
    		{
    			c.r = 255;
    			c.g = 255;
    			c.b = 255;
    		}
    
    		return c;
    	}
    
    #endif //DRAW_H
    
    /*vtr2<coord> pathCoords(warpings.size());
    for (int i = 0; i < warpings.size(); i++)
    pathCoords[i] = warpings[i].convert_toCoords();*/
    
    
    /*for (size_t i = 0; i < warpings.size(); i++)
    for(size_t j = 0; j < ranges[i].size(); j++)
    for (size_t k = ranges[i][j].start; k < ranges[i][j].end; k++)
    img.draw_point(warpings[i].pathCoords[k].col - 1, warpings[i].pathCoords[k].row - 1, green);*/