#include "source_file.h"
#include <string.h>
#include <windows.h>
#include <gdiplus.h>
#include <iostream>
#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"
#include <comdef.h>
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
static bool gGDIplusInit = false;
static ULONG_PTR gdiplusToken;
static GdiplusStartupInput gdiplusStartupInput;
typedef struct {
UINT Flags;
UINT Count;
ARGB Entries[256];
} GrayColorPalette;
GrayColorPalette GCP;
void startGDIplus()
{
if(GdiplusStartup(&gdiplusToken,&gdiplusStartupInput,NULL)==Ok)
{
gGDIplusInit = true;
}
else
{
return;
}
GCP.Flags = PaletteFlagsGrayScale;// initialize the color palette for grayscale images;
GCP.Count = 256;
for(int i=0;i<256;i++)
{
GCP.Entries[i]=Color::MakeARGB(255,i,i,i);
}
}
//-------------------------------------------------------load/save image---------------------------------------
bool qx_image_size_png(const char*filename,int &h,int &w)
{
size_t origsize=strlen(filename)+1;
const size_t newsize=500;
size_t convertedChars=0;
wchar_t wcstring[newsize];
_bstr_t bstrt(filename);
wcscpy_s(wcstring,(wchar_t*)bstrt);
if(!gGDIplusInit) startGDIplus();
Bitmap*image=new Bitmap(wcstring);
if(image->GetLastStatus()!= Ok)
{
std::cout << "cvLoadImage:: Unable to load" << wcstring << "\n";
h=w=0;
delete image;
return(false);
}
w =image->GetWidth();
h =image->GetHeight();
delete image;
return(true);
}
bool qx_loadimage_png(const char*filename,unsigned char*image,int h,int w,bool use_rgb)
{
size_t origsize=strlen(filename)+1;
const size_t newsize=500;
size_t convertedChars=0;
wchar_t wcstring[newsize];
_bstr_t bstrt(filename);
wcscpy_s(wcstring,(wchar_t*)bstrt);
if(!gGDIplusInit) startGDIplus();
Bitmap*image_read=new Bitmap(wcstring);
if(image_read->GetLastStatus()!= Ok)
{
std::cout << "cvLoadImage:: Unable to load" << wcstring << "\n";
h=w=0;
delete image_read;
return(false);
}
BitmapData* bitmapData = new BitmapData;
Rect rect(0, 0, w, h);
// Lock the entire bitmap for reading.
Status rst;
if((rst=image_read->LockBits(&rect,ImageLockModeRead,PixelFormat24bppRGB,bitmapData))!= Ok)
{
printf("error locking bits in %s, %d\n", __FILE__, __LINE__);
delete bitmapData;
delete image_read;
return(false);
}
UINT* pixels = (UINT*)bitmapData->Scan0;
byte*p=(byte*)pixels;
int nOffset=bitmapData->Stride-w*3;
if(use_rgb)
{
for(int y=0;y<h;y++)
{
for(int x=0;x<w;x++)
{
unsigned char b=*p++;
unsigned char g=*p++;
unsigned char r=*p++;
*image++=r; *image++=g; *image++=b;
}
p+=nOffset;
}
}
else
{
for(int y=0;y<h;y++)
{
for(int x=0;x<w;x++)
{
unsigned char b=*p++;
unsigned char g=*p++;
unsigned char r=*p++;
*image++=unsigned char(0.299*r+0.587*g+0.114*b+0.5);
}
p+=nOffset;
}
}
image_read->UnlockBits(bitmapData);
delete bitmapData;
delete image_read;
return(true);
}
void saveimage_pgm(char *filename,unsigned char **image,int h,int w,int scale)
{
unsigned char *image_u; int counter,y,x;
counter=0;
image_u=new unsigned char [h*w];
for (y=0;y<h;y++) for(x=0;x<w;x++)
image_u[counter++]=image[y][x]*scale;
write_binary_pgm(filename,image_u,h,w);
delete image_u;
}
void write_binary_pgm(char* filename,unsigned char *image,int h,int w)
{
FILE* file_out;
//file_out=fopen(filename,"wb");
fopen_s(&file_out,filename,"wb");
if(file_out==NULL)
{
printf("Can't open the file %s, exit!\n",filename);
getchar();
exit(0);
}
fprintf(file_out,"P5\n%d %d\n%d\n",w,h,255);
fwrite(image,sizeof(unsigned char),w*h,file_out);
fclose(file_out);
}
//-------------------------------------------------------box filtering operation--------------------------------
void boxcar_sliding_window(double**out,double**in,double**temp,double*temp_1w,double sigma_spatial,int h,int w)
{
int radius=qx_round(sigma_spatial*w);/*horizontal filtering*/
//printf("radius: [%d]\n",radius);
if(radius<(w>>1))
{
boxcar_sliding_window_x(temp[0],in[0],h,w,radius);/*horizontal filtering*/
boxcar_sliding_window_y(out[0],temp[0],temp_1w,h,w,qx_round(sigma_spatial*h));
}
else
{
memset(out[0],0,sizeof(double)*h*w);
}
}
void boxcar_sliding_window_x(double *out,double *in,int h,int w,int radius)
{
double scale=1.0/(2*radius+1);
for (int y = 0; y < h; y++) {
double t;
// do left edge
t = in[y*w] * radius;
for (int x = 0; x < radius+1; x++) {
t += in[y*w+x];
}
out[y*w] = t * scale;
if((radius*2+1)<w)
{
for(int x = 1; x < radius+1; x++) {
int c = y*w+x;
t += in[c+radius];
t -= in[y*w];
out[c] = t * scale;
}
// main loop
for(int x = radius+1; x < w-radius; x++) {
int c = y*w+x;
t += in[c+radius];
t -= in[c-radius-1];
out[c] = t * scale;
}
// do right edge
for (int x = w-radius; x < w; x++) {
int c = y*w+x;
t += in[(y*w)+w-1];
t -= in[c-radius-1];
out[c] = t * scale;
}
}
else
{
int xr=w-1-radius;
for(int x=1;x<=xr;x++)
{
int c = y*w+x;
t += in[c+radius];
t -= in[y*w];
out[c] = t * scale;
}
for(int x=xr+1;x<w;x++)
{
int c = y*w+x;
t += in[(y*w)+w-1];
if(c-radius-1>=0) t -= in[c-radius-1];
else t-=in[y*w];
out[c] = t * scale;
}
}
}
}
void boxcar_sliding_window_y(double *out,double *in,double*temp_1w,int h,int w,int radius)
{
double scale = 1.0/(2*radius+1);
for(int x=0;x<w;x++) temp_1w[x]=in[x]*radius;
for(int y=0;y<radius+1;y++)
{
for(int x=0;x<w;x++)
{
temp_1w[x]+=in[y*w+x];
}
}
for(int x=0;x<w;x++) out[x]=temp_1w[x]*scale;
for(int y=1;y<radius+1;y++)
{
for(int x=0;x<w;x++)
{
int c=y*w+x;
temp_1w[x]+=in[c+radius*w];
temp_1w[x]-=in[x];
out[c]=temp_1w[x]*scale;
}
}
for(int y=radius+1;y<h-radius;y++)
{
for(int x=0;x<w;x++)
{
int c=y*w+x;
temp_1w[x]+=in[c+radius*w];
temp_1w[x]-=in[c-(radius*w)-w];
out[c]=temp_1w[x]*scale;
}
}
for(int y=h-radius;y<h;y++)
{
for(int x=0;x<w;x++)
{
int c=y*w+x;
temp_1w[x]+=in[(h-1)*w+x];
temp_1w[x]-=in[c-(radius*w)-w];
out[c]=temp_1w[x]*scale;
}
}
}
//-------------------------------------------------------ax=b solver--------------------------------------------
qx_conjugated_gradient_double::qx_conjugated_gradient_double()
{
m_ata=NULL;
m_atb=NULL;
m_d=NULL;
m_ad=NULL;
m_r=NULL;
}
qx_conjugated_gradient_double::~qx_conjugated_gradient_double()
{
clean();
}
void qx_conjugated_gradient_double::clean()
{
qx_freed(m_ata); m_ata=NULL;
if(m_atb!=NULL) delete [] m_atb; m_atb=NULL;
if(m_d!=NULL) delete [] m_d; m_d=NULL;
if(m_ad!=NULL) delete [] m_ad; m_ad=NULL;
if(m_r!=NULL) delete [] m_r; m_r=NULL;
}
int qx_conjugated_gradient_double::init(int len)
{
clean();
m_len=len;
m_ata=qx_allocd(len,len);
m_atb=new double [len];
m_d=new double [len];
m_ad=new double [len];
m_r=new double [len];
return(0);
}
double qx_conjugated_gradient_double::solver(double *x,double **a,double *b,int n,int m,double accuracy,bool is_symmetry)
{
double error;
if(m_len<m)
{
printf("len<m, allocated memory is not enough!");
getchar();
return(-1);
}
if(is_symmetry)
{
error=solver_symmetry(a,b,x,m_d,m_r,m_ad,m,accuracy);
}
else
{
qx_ata_dn(m_ata,a,n,m);
qx_atb_dn(m_atb,a,b,n,m);
error=solver_symmetry(m_ata,m_atb,x,m_d,m_r,m_ad,m,accuracy);
}
return(error);
}
double qx_conjugated_gradient_double::solver_symmetry(double **ata,double *atb,double *x,double *d,double *r,double *ad,int len,
double accuracy)
{
double mse=accuracy*1