#include "stdafx.h"
|
#include "ImageFunc.h"
|
#include <WinGDI.h>
|
#include <omp.h>
|
#include <math.h>
|
#include <intrin.h>
|
#include "../Functions.hpp"
|
#include "../MHashINI/MHash.hpp"
|
#define Pi 3.1415926535897932384626433
|
|
using namespace Gdiplus;
|
#pragma comment(lib,"gdiplus.lib")
|
|
int MyImage::AllocBuf(int width,int height,int stride,int PixelFormat1)
|
{
|
if (ShowCache != NULL) { ::delete ShowCache; ShowCache = NULL; }
|
//stride ,ÒÔ64×Ö½Ú¶ÔÆë?
|
if (stride==0) {stride=(width+Stride_Align-1)&(-Stride_Align);}
|
if (buffer0!=NULL)
|
{
|
if (width==this->Width&&height==this->Height&&stride==this->Stride)
|
{
|
this->PixelFormat=PixelFormat1;
|
m_thumbImg.IsValid=0;
|
return true;
|
}
|
delete[] buffer0;
|
delete[] buffer2;
|
delete[] buffer3;
|
|
}
|
buffer0=new unsigned char[stride*height+Stride_Align];
|
buffer=(void *)(((INT_PTR)buffer0+Stride_Align-1)&(INT_PTR)(-Stride_Align));
|
this->Width=width;
|
this->Height=height;
|
this->Stride=stride;
|
if (PixelFormat1!=0) this->PixelFormat=PixelFormat1;
|
else {this->PixelFormat=MyPixelType_Mono8;}
|
if (PixelFormat1 == MyPixelType_RGB8planar)
|
{
|
buffer2 = new unsigned char[stride*height + Stride_Align];
|
buffer3 = new unsigned char[stride*height + Stride_Align];
|
}
|
IsValid=true;
|
|
return true;
|
}
|
|
int MyImage::CopyFromGdipBitMap(Gdiplus::Bitmap * bitmap1)
|
{
|
if (bitmap1==NULL) {return -1;}
|
int w,h;
|
w=bitmap1->GetWidth();
|
h=bitmap1->GetHeight();
|
Rect rect1;
|
rect1.X=0;rect1.Y=0;rect1.Width=w;rect1.Height=h;
|
BitmapData bitmapData1;
|
|
Gdiplus::PixelFormat pixelformat = bitmap1->GetPixelFormat();
|
if (pixelformat==PixelFormat8bppIndexed)
|
{
|
bitmap1->LockBits(&rect1,ImageLockModeRead,PixelFormat8bppIndexed,&bitmapData1);
|
int stride1=bitmapData1.Stride;
|
unsigned char * buf1=(unsigned char *)bitmapData1.Scan0;
|
int r=CopyFromBuf(buf1,w,h,stride1,MyPixelType_Mono8);
|
}else
|
{
|
bitmap1->LockBits(&rect1,ImageLockModeRead,PixelFormat32bppRGB,&bitmapData1);
|
int stride1=bitmapData1.Stride;
|
DWORD * buf1=(DWORD *)bitmapData1.Scan0;
|
// this->AllocBuf(w,h);
|
// int stride2=this->Stride;
|
// unsigned char * pixels=(unsigned char *)buffer;
|
// for (int i=0;i<h;i++)
|
// {
|
// int l1=i*stride1/4;
|
// int l=i*stride2;
|
// for (int j=0;j<w;j++)
|
// {
|
// COLOR c1;
|
// c1.argb=buf1[l1+j];
|
// pixels[l+j]=RGBtoVI(c1.R,c1.G,c1.B);
|
// }
|
// }
|
int r=CopyFromBuf(buf1,w,h,stride1,MyPixelType_ARGB32);
|
}
|
bitmap1->UnlockBits(&bitmapData1);
|
return 1;
|
}
|
|
int MyImage::LoadFromBitmapFile(CString sFilePathName)
|
{
|
Bitmap bitmap1(sFilePathName);
|
this->CopyFromGdipBitMap(&bitmap1);
|
int j = sFilePathName.MakeUpper().Find(_T(".RAW"));
|
if ( j!= -1)
|
{
|
int k = this->PixelFormat;
|
if ( k == MyPixelType_Mono8)
|
{
|
this->PixelFormat = MyPixelType_BayerGR8;
|
}
|
|
}
|
return 0;
|
}
|
|
int MyImage::SaveToFile(CString sFilePathName)
|
{
|
if (this->PixelFormat == MyPixelType_RGB8planar)
|
{
|
return 0;
|
|
}if (this->PixelFormat == MyPixelType_ARGB32)
|
{
|
Bitmap * bitmap1=NULL;
|
ConvertTypeToGdipBitmap32(&bitmap1);
|
int r=SaveGdiPImageAsFile(bitmap1, sFilePathName);
|
return r;
|
}
|
else
|
{
|
int r = SaveBufferToBmpFile(buffer, Width, Height, Stride, sFilePathName, 0, 0);
|
return r;
|
}
|
}
|
|
int MyImage::LoadRegionFromFile(CString sFilePathName)
|
{
|
myregions.clear();
|
MHash RegionCfg;
|
RegionCfg.LoadFromFile(sFilePathName);
|
|
int k = _tstoi(RegionCfg["Regions"]["TotalRegion"]);
|
for (int i = 0; i < k; i++)
|
{
|
MyRegion thisRegion;
|
|
CString RegionNo;
|
RegionNo.Format(_T("Region%d"), i + 1);
|
thisRegion.IsValid = _tstoi(RegionCfg[RegionNo]["IsValid"]);
|
thisRegion.RegionStr = RegionCfg[RegionNo]["Str"];
|
thisRegion.RegionColor = _tstoi(RegionCfg[RegionNo]["Color"]);
|
int PtCount=_tstoi(RegionCfg[RegionNo]["PtCount"]);
|
|
CString ResultStr[10];
|
for (int j = 0; j < PtCount; j++)
|
{
|
CString PtNo;
|
PtNo.Format(_T("Pt%d"), j + 1);
|
CString thisptstr = RegionCfg[RegionNo][PtNo];
|
Split(thisptstr, _T(","), ResultStr);
|
MyPoint thispt;
|
thispt.X = _tstoi(ResultStr[0]);
|
thispt.Y = _tstoi(ResultStr[1]);
|
thisRegion.pts.push_back(thispt);
|
}
|
myregions.push_back(thisRegion);
|
}
|
return 0;
|
}
|
int MyImage::SaveRegionToFile(CString sFilePathName)
|
{
|
CString s1;
|
MHash RegionCfg;
|
int k = myregions.size();
|
s1.Format(_T("%d"), k);
|
RegionCfg["Regions"]["TotalRegion"]=s1;
|
for (int i = 0; i < k; i++)
|
{
|
MyRegion thisRegion;
|
thisRegion = myregions.at(i);
|
|
CString RegionNo;
|
RegionNo.Format(_T("Region%d"), i + 1);
|
s1.Format(_T("%d"), thisRegion.IsValid);
|
RegionCfg[RegionNo]["IsValid"]=s1;
|
RegionCfg[RegionNo]["Str"]=thisRegion.RegionStr;
|
s1.Format(_T("%d"), thisRegion.RegionColor);
|
RegionCfg[RegionNo]["Color"]=s1;
|
|
int PtCount = thisRegion.pts.size();
|
s1.Format(_T("%d"), PtCount);
|
RegionCfg[RegionNo]["PtCount"]=s1;
|
|
for (int j = 0; j < PtCount; j++)
|
{
|
CString PtNo;
|
MyPoint thispt;
|
PtNo.Format(_T("Pt%d"), j + 1);
|
thispt = thisRegion.pts.at(j);
|
s1.Format(_T("%d,%d"), thispt.X, thispt.Y);
|
RegionCfg[RegionNo][PtNo]=s1;
|
}
|
}
|
RegionCfg.SaveToFile(sFilePathName);
|
return 0;
|
}
|
|
int MyImage::CopyFromBuf(void * buf,int w,int h,int stride,int pixelformat)
|
{
|
if (stride==0)
|
{
|
stride=(w+Stride_Align-1)&(-Stride_Align);
|
}
|
|
SN=0;
|
|
if (pixelformat==MyPixelType_BayerGB8)
|
{
|
int bpp = stride/w;
|
int newstride = stride - 2*bpp;
|
AllocBuf(w-2,h-2,newstride,pixelformat);
|
for (int i=0; i<h-2; ++i)
|
{
|
memcpy((char*)buffer+i*newstride,(char*)buf+(i+1)*stride+bpp,newstride);
|
}
|
this->PixelFormat=MyPixelType_BayerGR8;
|
}else
|
{
|
AllocBuf(w,h,stride,pixelformat);
|
memcpy(buffer,buf,h*stride);
|
}
|
// this->PixelFormat=pixelformat;
|
return true;
|
};
|
|
int MyImage::CopyFromBufR90(void * buf,int w,int h,int stride,int pixelformat)
|
{
|
AllocBuf(h,w,h,pixelformat);
|
for (int i=0;i<w;i++)
|
{
|
for (int j=0;j<h;j++)
|
{
|
((UCHAR *)buffer)[i*Stride+j]=((UCHAR *)buf)[(j)*stride+(w-i-1)];
|
}
|
}
|
// memcpy(buffer,buf,h*stride);
|
this->PixelFormat=MyPixelType_Mono8;
|
return true;
|
};
|
|
int MyImage::Meg3ImgIntoRGB8planar(MyImage & img1, MyImage &img2, MyImage & img3)
|
{
|
int nwidth, nheight, nstride;
|
nwidth = img1.Width;
|
nheight = img1.Height;
|
nstride = img1.Stride ;
|
this->PixelFormat = MyPixelType_RGB8planar;
|
AllocBuf(nwidth, nheight, nstride, MyPixelType_RGB8planar );
|
|
memcpy(buffer, img1.buffer, nwidth*nheight);
|
memcpy(buffer2, img2.buffer, nwidth*nheight);
|
memcpy(buffer3, img3.buffer, nwidth*nheight);
|
return 0;
|
}
|
|
int MyImage::Meg3ImgIntoRGB(MyImage & img1, MyImage &img2, MyImage & img3)
|
{
|
int nwidth, nheight, nstride;
|
nwidth = img1.Width;
|
nheight = img1.Height;
|
nstride = img1.Stride * 4;
|
this->PixelFormat = MyPixelType_ARGB32;
|
AllocBuf(nwidth, nheight, nstride, MyPixelType_ARGB32);
|
|
for (int i = 0; i < nheight; i++)
|
{
|
unsigned char * line1 = (unsigned char *)img3.buffer + i*img1.Stride;
|
unsigned char * line2 = (unsigned char *)img2.buffer + i*img2.Stride;
|
unsigned char * line3 = (unsigned char *)img1.buffer + i*img3.Stride;
|
unsigned char * line5 = (unsigned char *)buffer + i*nstride;
|
for (int j = 0; j < nwidth; j+=4)
|
{
|
line5[j*4 ] = line1[j];
|
line5[j*4+1] = line2[j];
|
line5[j*4+2] = line3[j];
|
|
line5[j * 4 + 4] = line1[j+1];
|
line5[j * 4 + 5] = line2[j+1];
|
line5[j * 4 + 6] = line3[j+1];
|
|
line5[j * 4 + 8] = line1[j+2];
|
line5[j * 4 + 9] = line2[j+2];
|
line5[j * 4 + 10] = line3[j+2];
|
|
line5[j * 4 + 12] = line1[j+3];
|
line5[j * 4 + 13] = line2[j+3];
|
line5[j * 4 + 14] = line3[j+3];
|
/*
|
c1.R = line1[j+4];
|
c1.G = line2[j + 4];
|
c1.B = line3[j + 4];
|
line5[j + 4] = c1.argb;
|
c2.R = line1[j + 5];
|
c2.G = line2[j + 5];
|
c2.B = line3[j + 5];
|
line5[j + 5] = c2.argb;
|
c3.R = line1[j + 6];
|
c3.G = line2[j + 6];
|
c3.B = line3[j + 6];
|
line5[j + 6] = c3.argb;
|
c4.R = line1[j + 7];
|
c4.G = line2[j + 7];
|
c4.B = line3[j + 7];
|
line5[j + 7] = c4.argb;
|
//*/
|
}
|
}
|
return 0;
|
}
|
|
int MyImage::CreateThumbImg(int Width, int Height,float startX, float startY , float swidth, float sheight )
|
{
|
if (!IsValid) return -1;
|
int nThumbWidth, nThumbHeight;
|
float nSrcStartX, nSrcStartY, nSrcWidth, nSrcHeight;
|
if (Width == 0 || Height == 0)
|
{
|
nThumbWidth = 1280;
|
nThumbHeight = 960;
|
nSrcStartX = 0; nSrcStartY = 0; nSrcWidth = this->Width; nSrcHeight = this->Height;
|
}
|
else
|
{
|
nThumbWidth = Width;
|
nThumbHeight = Height;
|
if (swidth == 0 || sheight == 0)
|
{
|
nSrcStartX = 0; nSrcStartY = 0; nSrcWidth = this->Width; nSrcHeight = this->Height;
|
}
|
else
|
{
|
nSrcStartX = startX; nSrcStartY = startY;
|
nSrcWidth = swidth; nSrcHeight = sheight;
|
}
|
}
|
if (m_thumbImg.buffer&&m_thumbImg.nWidth != nThumbWidth || m_thumbImg.nHeight != nThumbHeight)
|
{
|
delete m_thumbImg.buffer; m_thumbImg.buffer = nullptr;
|
}
|
m_thumbImg.nWidth = nThumbWidth;
|
m_thumbImg.nHeight = nThumbHeight;
|
if (this->PixelFormat == MyPixelType_ARGB32)
|
{
|
if (m_thumbImg.buffer == 0)
|
{
|
m_thumbImg.buffer = new DWORD[nThumbWidth * nThumbHeight ];
|
}
|
for (int i = 0; i < nThumbHeight; i++)
|
{
|
DWORD * line1 = (DWORD *)buffer + int(i*nSrcHeight / nThumbHeight+nSrcStartY) * (Stride/4);
|
DWORD * tline1 = (DWORD *)m_thumbImg.buffer + i * nThumbWidth;
|
for (int j = 0; j < nThumbWidth; j++)
|
{
|
tline1[j] = line1[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
|
//tline1[j] = 255;
|
}
|
}
|
m_thumbImg.IsValid = 1;
|
}
|
else if (this->PixelFormat == MyPixelType_RGB8planar)
|
{
|
if (m_thumbImg.buffer == 0)
|
{
|
m_thumbImg.buffer = new DWORD[(nThumbWidth+3)/4*4 * (nThumbHeight+1)/2*2];
|
}
|
for (int i = 0; i < nThumbHeight; i++)
|
{
|
unsigned char * line1 = (unsigned char *)buffer + int(i*nSrcHeight / nThumbHeight + nSrcStartY) * (Stride);
|
unsigned char * line2 = (unsigned char *)buffer2 + int(i*nSrcHeight / nThumbHeight + nSrcStartY) * (Stride);
|
unsigned char * line3 = (unsigned char *)buffer3 + int(i*nSrcHeight / nThumbHeight + nSrcStartY) * (Stride);
|
|
|
DWORD * tline1 = (DWORD *)m_thumbImg.buffer + i * nThumbWidth;
|
for (int j = 0; j < nThumbWidth; j++)
|
{
|
COLOR * c1 = (COLOR *)&(tline1[j]);
|
c1->R = line1[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
|
c1->G = line2[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
|
c1->B = line3[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
|
|
//tline1[j] = 255;
|
}
|
}
|
m_thumbImg.IsValid = 1;
|
}
|
else if (this->PixelFormat == MyPixelType_BayerGR8 || this->PixelFormat == MyPixelType_BayerGB8)
|
{
|
if (m_thumbImg.buffer == 0)
|
{
|
m_thumbImg.buffer = new unsigned char[(nThumbWidth + 3) / 4 * 4 * (nThumbHeight + 1) / 2 * 2];
|
}
|
|
for (int i = 0; i < nThumbHeight; i+=2)
|
{
|
unsigned char * line1 = (unsigned char *)buffer + (int(i*nSrcHeight / nThumbHeight + nSrcStartY) & 0xfffffffe) * Stride;
|
unsigned char * tline1 = (unsigned char *)m_thumbImg.buffer + i * nThumbWidth;
|
unsigned char * line2 = (unsigned char *)buffer + ((int(i*nSrcHeight / nThumbHeight + nSrcStartY) & 0xfffffffe) + 1) * Stride;
|
unsigned char * tline2 = (unsigned char *)m_thumbImg.buffer + (i+1) * nThumbWidth;
|
|
for (int j = 0; j < nThumbWidth; j+=2)
|
{
|
tline1[j] = line1[int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe];
|
tline1[j + 1] = line1[(int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe) + 1];
|
tline2[j] = line2[int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe];
|
tline2[j + 1] = line2[(int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe) + 1];
|
//tline1[j] = 255;//line1[(j*this->Width / nWidth)&0xfffffffe];
|
//tline1[j+1] = 0;//line1[((j*this->Width / nWidth)&0xfffffffe)+1];
|
//tline2[j] = 0;//line2[(j*this->Width / nWidth)&0xfffffffe];
|
//tline2[j+1] = 255;//line2[((j*this->Width / nWidth)&0xfffffffe)+1];
|
}
|
}
|
m_thumbImg.IsValid = 1;
|
}
|
else
|
{
|
if (m_thumbImg.buffer == 0)
|
{
|
m_thumbImg.buffer = new unsigned char[nThumbWidth * nThumbHeight];
|
}
|
for (int i = 0; i < nThumbHeight; i++)
|
{
|
unsigned char * line1 = (unsigned char *)buffer + int(i*nSrcHeight / nThumbHeight+nSrcStartY) * Stride;
|
unsigned char * tline1 = (unsigned char *)m_thumbImg.buffer + i * nThumbWidth;
|
for (int j = 0; j < nThumbWidth; j++)
|
{
|
tline1[j] = line1[int(j*nSrcWidth / nThumbWidth+nSrcStartX)];
|
}
|
}
|
m_thumbImg.IsValid = 1;
|
}
|
|
return 0;
|
}
|
int MyImage::DrawOnWindow(HWND hWnd,int Brightness,int Contrast)
|
{
|
|
/*
|
if (this->IsHistoValid)
|
{
|
Graphics gr1(bitmap1);
|
Pen pen1(Color(255,255,255,255),1);
|
for (int i=0;i<256;i++)
|
{
|
int Length=this->HistoArray[i]*512/this->MaxHistoCount;
|
if (Length>255) {Length=255;}
|
gr1.DrawLine(&pen1,i,256,i,1);
|
}
|
}
|
*/
|
CString s1;
|
s1.Format(_T("SN:%d %s "),this->SN,this->Name);
|
s1+=InfoStr;
|
CString * Lable;
|
Lable = &s1;
|
// DrawBitmapOnWindow(hWnd,bitmap1,&s1,&ResultStr);
|
|
// if (bitmap1 == NULL) return 0;
|
if (hWnd == NULL) return 0;
|
if (!IsWindow(hWnd)) return 0;
|
if (!IsWindowVisible(hWnd)) return 0;
|
|
int srcw, srch;
|
srcw = this->Width;
|
srch = this->Height;
|
if (srcw == 0 || srch == 0) return 0;
|
|
RECT rect0;
|
GetClientRect(hWnd, &rect0);
|
int clientw, clienth; //¿Í»§Çøʵ¼ÊµÄ¿í¶ÈºÍ¸ß¶È
|
clientw = rect0.right - rect0.left;
|
clienth = rect0.bottom - rect0.top;
|
|
SolidBrush brush1(Color(255, 0, 0, 0)); //дºÚ×Ö
|
SolidBrush brush2(Color(255, 255, 255, 255)); //д°××Ö
|
int w1, h1; //ͼƬÔÚ¿Í»§ÇøÏÔʾʱµÄ¿í¶ÈºÍ¸ß¶È,
|
//¿¼Âǵ½±£³Ö¿í¸ß±È£¬Óë¿Í»§Çø´óС²»Ò»¶¨Ïàͬ
|
int startx, starty;
|
//ͼƬÔÚ¿Í»§ÇøµÄÆðʼλÖÃ;
|
|
if (srcw*rect0.bottom == srch*rect0.right)
|
{
|
w1 = clientw;
|
h1 = clienth;
|
startx = rect0.left;
|
starty = rect0.top;
|
|
}
|
else if (srcw*rect0.bottom>srch*rect0.right) //ͼƬºáÏò´ó£¬¸ß¶È²»Âú
|
{
|
w1 = clientw;
|
h1 = clientw*srch / srcw;
|
startx = rect0.left;
|
starty = rect0.top + (clienth - h1) / 2;
|
}
|
else //ͼƬ×ÝÏò´ó,¿í¶È²»Âú
|
{
|
w1 = clienth*srcw / srch;
|
h1 = clienth;
|
startx = rect0.left + (clientw - w1) / 2;
|
starty = rect0.top;
|
}
|
Bitmap *bitmap1 = NULL;
|
if (IsToRefreshCache||ShowCache != NULL && (ShowCache->GetWidth() != w1 || ShowCache->GetHeight() != h1))
|
{
|
::delete ShowCache;
|
ShowCache = NULL;
|
IsToRefreshCache = 0;
|
}
|
if (ShowCache == NULL)
|
{
|
Rect rect4;
|
rect4.X = 0;
|
rect4.Y = 0;
|
rect4.Width = w1;
|
rect4.Height = h1;
|
ConvertTypeToGdipBitmap32(&bitmap1, Brightness, Contrast);
|
ShowCache = ::new Bitmap(w1, h1);
|
Graphics gr4(ShowCache);
|
gr4.DrawImage(bitmap1,rect4);
|
|
//------------ ÏÔʾ Region
|
|
int n = myregions.size();
|
for (int i = 0; i < n; i++)
|
{
|
MyRegion thisregion = myregions.at(i);
|
int k = thisregion.pts.size();
|
if (thisregion.IsValid)
|
{
|
Pen pen1(Color(255,255,0,0), 1);
|
MyPoint lastPt = thisregion.pts.at(k - 1);
|
for (int j = 0; j < k; j++)
|
{
|
MyPoint pt1 = thisregion.pts.at(j);
|
gr4.DrawRectangle(&pen1, pt1.X*w1 / srcw - 2, pt1.Y*h1 / srch - 2 , 4, 4);
|
gr4.DrawLine(&pen1, pt1.X*w1 / srcw , pt1.Y*h1 / srch, lastPt.X*w1 / srcw, lastPt.Y*h1 / srch);
|
lastPt = pt1;
|
}
|
}
|
}
|
//-----------------------------------------------------------
|
///*
|
|
if (Lable != NULL&&!Lable->IsEmpty())
|
{
|
CStringW sw1;
|
TToW(*Lable, sw1);
|
// Pen pen1(Color(255,0,0,0),1); //»ºÚÏß
|
Pen pen2(Color(128, 128, 128, 128), 0.5); //»»ÒÏß
|
|
FontFamily fontfamily1(L"ºÚÌå");
|
int fontsize = h1 / 60;
|
if (fontsize<16) { fontsize = 16; }
|
Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
|
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
StringFormat stringformat1;
|
stringformat1.SetAlignment(StringAlignmentNear);
|
stringformat1.SetLineAlignment(StringAlignmentNear);
|
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(0.0f, 0.0f), &stringformat1, &brush1);
|
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(2.0f, 2.0f), &stringformat1, &brush1);
|
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(0.0f, 2.0f), &stringformat1, &brush1);
|
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(2.0f, 0.0f), &stringformat1, &brush1);
|
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(1.0f, 1.0f), &stringformat1, &brush2);
|
}
|
if (!ResultStr.IsEmpty())
|
{
|
CStringW sw1;
|
TToW(ResultStr, sw1);
|
// Pen pen1(Color(255,0,0,0),1); //»ºÚÏß
|
Pen pen2(Color(128, 128, 128, 128), 0.5); //»»ÒÏß
|
SolidBrush brush3(Color(255, 0, 0, 0)); //дºÚ×Ö
|
SolidBrush brush4(Color(128, 0, 255, 0)); //дÂÌ×Ö
|
|
FontFamily fontfamily1(L"ºÚÌå");
|
int fontsize = h1 / 4;
|
if (fontsize<48) { fontsize = 48; }
|
Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
|
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
StringFormat stringformat1;
|
stringformat1.SetAlignment(StringAlignmentCenter);
|
stringformat1.SetLineAlignment(StringAlignmentCenter);
|
float centerx, centery;
|
centerx = (w1) / 2;
|
centery = (h1) / 2;
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+0.0f),&stringformat1,&brush3);
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+2.0f),&stringformat1,&brush3);
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+2.0f),&stringformat1,&brush3);
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+0.0f),&stringformat1,&brush3);
|
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(centerx + 1.0f, centery + 1.0f), &stringformat1, &brush4);
|
}
|
|
gr4.Flush();
|
|
}
|
Rect rect1;
|
rect1.X = startx;
|
rect1.Y = starty;
|
rect1.Width = w1;
|
rect1.Height = h1;
|
|
HDC hdc1 = GetDC(hWnd);
|
Graphics gr1(hdc1);
|
|
gr1.DrawImage(ShowCache, rect1); //»Í¼Ïñ
|
if (startx != 0) //ÔÚͼÏñµÄÁ½²à»±³¾°
|
{
|
gr1.FillRectangle(&brush1, 0, 0, startx, clienth);
|
gr1.FillRectangle(&brush1, startx + w1, 0, startx, clienth);
|
}
|
if (starty != 0)
|
{
|
gr1.FillRectangle(&brush1, 0, 0, clientw, starty);
|
gr1.FillRectangle(&brush1, 0, starty + h1, clientw, starty);
|
}
|
|
// gr1.Flush();
|
//*/
|
ReleaseDC(hWnd, hdc1);
|
|
if (bitmap1!=NULL) ::delete bitmap1;
|
return 1;
|
};
|
int MyImage::DrawThumbOnWindow(HWND hWnd, int Brightness, int Contrast)
|
{
|
if (!m_thumbImg.IsValid) CreateThumbImg();
|
Bitmap *bitmap1 = NULL;
|
ConvertThumbToGdipBitmap32(&bitmap1, Brightness, Contrast);
|
/*
|
if (this->IsHistoValid)
|
{
|
Graphics gr1(bitmap1);
|
Pen pen1(Color(255,255,255,255),1);
|
for (int i=0;i<256;i++)
|
{
|
int Length=this->HistoArray[i]*512/this->MaxHistoCount;
|
if (Length>255) {Length=255;}
|
gr1.DrawLine(&pen1,i,256,i,1);
|
}
|
}
|
*/
|
CString s1;
|
s1.Format(_T("SN:%d %s "), this->SN, this->Name);
|
s1 += InfoStr;
|
DrawBitmapOnWindow(hWnd, bitmap1, &s1, &ResultStr);
|
::delete bitmap1;
|
return 1;
|
};
|
int MyImage::ConvertTypeToGdipBitmap32(Gdiplus::Bitmap** bitmapdest,int Brightness,int Contrast)
|
{
|
/*
|
PixelType_Mono8
|
PixelType_BayerGB8
|
PixelType_BayerGB12
|
PixelType_YUV422packed
|
PixelType_YUV422_YUYV_Packed
|
PixelType_BayerGB12Packed
|
*/
|
int i,j,k,l;
|
int w,h;
|
w=this->Width;
|
h=this->Height;
|
int pixeltype;
|
pixeltype=this->PixelFormat;
|
if (*bitmapdest==NULL)
|
{
|
*bitmapdest=::new Gdiplus::Bitmap(w,h);
|
}
|
else if ((*bitmapdest)->GetWidth()!=w&&(*bitmapdest)->GetHeight()!=h)
|
{
|
::delete *bitmapdest;*bitmapdest=NULL;
|
*bitmapdest=::new Gdiplus::Bitmap(w,h);
|
}
|
|
unsigned char * srcpixel=(unsigned char *)buffer;
|
Gdiplus::BitmapData bitmapdata1;
|
bitmapdata1.PixelFormat=PixelFormat32bppRGB;
|
Gdiplus::Rect rect1(0,0,w,h);
|
Gdiplus::Status GdipStatus=(*bitmapdest)->LockBits(&rect1,Gdiplus::ImageLockModeWrite,//|ImageLockModeUserInputBuf,
|
PixelFormat32bppRGB,&bitmapdata1);//PixelFormat32bppRGB
|
if (GdipStatus!=Gdiplus::Ok)
|
{
|
CString Errs1;
|
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
// SysLog(Errs1);
|
return 0;
|
}
|
COLOR c1;
|
UINT * pixels;
|
pixels=(UINT *)bitmapdata1.Scan0;
|
int s=bitmapdata1.Stride;
|
|
|
if (pixeltype==MyPixelType_Mono8)
|
{
|
for (i=0;i<h;i++)
|
{
|
k=i*(int)Stride;
|
l=i*s/4;
|
for (j=0;j<w;j++)
|
{
|
c1.R=srcpixel[k+j];
|
c1.G=c1.R;
|
c1.B=c1.R;
|
pixels[l+j]=c1.argb;
|
}
|
}
|
}
|
if (pixeltype==MyPixelType_ARGB32)
|
{
|
memcpy(pixels,buffer,h*Stride);
|
}
|
if (pixeltype==MyPixelType_BayerGR8)
|
{
|
BayerGR8toRGB32(buffer,bitmapdata1.Scan0,w,h,Stride,bitmapdata1.Stride);
|
}
|
if (pixeltype==MyPixelType_BayerGB8)
|
{
|
BayerGB8toRGB32(buffer,bitmapdata1.Scan0,w,h,Stride,bitmapdata1.Stride);
|
}
|
if (pixeltype==MyPixelType_BayerGB12)
|
{
|
Gdiplus::Bitmap* bitmapRaw8=NULL;
|
|
if (bitmapRaw8==NULL)
|
{
|
bitmapRaw8=::new Gdiplus::Bitmap(w,h,PixelFormat8bppIndexed);
|
}
|
if (bitmapRaw8->GetHeight()!=h||bitmapRaw8->GetWidth()!=w)
|
{
|
::delete bitmapRaw8;
|
bitmapRaw8=::new Gdiplus::Bitmap(w,h,PixelFormat8bppIndexed);
|
}
|
Gdiplus::ColorPalette * pal1=(Gdiplus::ColorPalette *) new unsigned char[1048];
|
pal1->Flags=2;
|
pal1->Count=256;
|
int i;
|
for (i=0;i<256;i++)
|
{
|
pal1->Entries[i]=Gdiplus::Color::MakeARGB(255,i,i,i);
|
}
|
|
bitmapRaw8->SetPalette(pal1);
|
delete [] pal1;
|
|
Gdiplus::Rect rect1(0,0,w,h);
|
Gdiplus::BitmapData bitmapdataRaw8;
|
bitmapdataRaw8.PixelFormat=PixelFormat8bppIndexed;
|
Gdiplus::Status GdipStatus=bitmapRaw8->LockBits(&rect1,Gdiplus::ImageLockModeWrite,PixelFormat8bppIndexed,&bitmapdataRaw8);
|
if (GdipStatus!=Gdiplus::Ok)
|
{
|
CString Errs1;
|
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
// SysLog(Errs1);
|
return 0;
|
}
|
Raw12ToRaw8(bitmapdataRaw8.Scan0,srcpixel,w,h);
|
bitmapRaw8->UnlockBits(&bitmapdataRaw8);
|
|
unsigned short *srcpixel2=(unsigned short *) srcpixel;
|
int r,g,b;
|
for (i=0;i<h;i+=2)
|
{
|
k=i*(int)Stride/2;
|
l=i*s/4;
|
|
//żÊýÐÐ
|
for (j=0;j<w;j+=2)
|
{
|
g=srcpixel2[k+j];
|
b=srcpixel2[k+j+1];
|
r=srcpixel2[k+Stride/2+j];
|
c1.R=r>>4;
|
c1.G=g>>4;
|
c1.B=b>>4;
|
pixels[l+j]=c1.argb;
|
pixels[l+j+1]=c1.argb;
|
}
|
//ÆæÊýÐÐ
|
for (j=0;j<w;j+=2)
|
{
|
g=srcpixel2[k+Stride/2+j+1];
|
b=srcpixel2[k+j+1];
|
r=srcpixel2[k+Stride/2+j];
|
c1.R=r>>4;
|
c1.G=g>>4;
|
c1.B=b>>4;
|
pixels[l+s/4+j]=c1.argb;
|
pixels[l+s/4+j+1]=c1.argb;
|
}
|
}
|
}
|
if (pixeltype==MyPixelType_YUV422packed)
|
{
|
int y,u,v;
|
int r,g,b;
|
for (i=0;i<h;i++)
|
{
|
k=i*(int)Stride;
|
l=i*s/4;
|
for (j=0;j<w;j+=2)
|
{
|
y=srcpixel[k+j*2+1];
|
u=srcpixel[k+(j/2)*4];
|
v=srcpixel[k+(j/2)*4+2];
|
r=int(y+1.402*(v-128));
|
g=int(y-0.34414*(u-128)-0.71414*(v-128));
|
b=int(y+1.772*(u-128));
|
if (r<0){r=0;}
|
if (g<0) {g=0;}
|
if (b<0) {b=0;}
|
|
if (r>255){r=255;}
|
if (g>255){g=255;}
|
if (b>255) {b=255;}
|
c1.R=r;
|
c1.G=g;
|
c1.B=b;
|
pixels[l+j]=c1.argb;
|
|
y=srcpixel[k+j*2+3];
|
r=int(y+1.402*(v-128));
|
g=int(y-0.34414*(u-128)-0.71414*(v-128));
|
b=int(y+1.772*(u-128));
|
if (r<0){r=0;}
|
if (g<0) {g=0;}
|
if (b<0) {b=0;}
|
|
if (r>255){r=255;}
|
if (g>255){g=255;}
|
if (b>255) {b=255;}
|
|
c1.R=r;
|
c1.G=g;
|
c1.B=b;
|
pixels[l+j+1]=c1.argb;
|
}
|
}
|
}
|
|
if (pixeltype==MyPixelType_YUV422_YUYV_Packed)
|
{
|
int y,u,v;
|
int r,g,b;
|
for (i=0;i<h;i++)
|
{
|
k=i*(int)Stride;
|
l=i*s/4;
|
for (j=0;j<w;j+=2)
|
{
|
y=srcpixel[k+j*2];
|
u=srcpixel[k+(j/2)*4+1];
|
v=srcpixel[k+(j/2)*4+3];
|
r=int(y+1.402*(v-128));
|
g=int(y-0.34414*(u-128)-0.71414*(v-128));
|
b=int(y+1.772*(u-128));
|
if (r<0){r=0;}
|
if (g<0) {g=0;}
|
if (b<0) {b=0;}
|
c1.R=(r>255?255:r);
|
c1.G=(g>255?255:g);
|
c1.B=(b>255?255:b);
|
pixels[l+j]=c1.argb;
|
|
y=srcpixel[k+j*2+2];
|
r=int(y+1.402*(v-128));
|
g=int(y-0.34414*(u-128)-0.71414*(v-128));
|
b=int(y+1.772*(u-128));
|
if (r<0){r=0;}
|
if (g<0) {g=0;}
|
if (b<0) {b=0;}
|
c1.R=(r>255?255:r);
|
c1.G=(g>255?255:g);
|
c1.B=(b>255?255:b);
|
pixels[l+j+1]=c1.argb;
|
}
|
}
|
}
|
//*/
|
if (this->PixelFormat==MyPixelType_BayerGB12_Packed)
|
{
|
//unsigned short *srcpixel2=(unsigned short *) srcpixel;
|
/*
|
int r,g,b;
|
for (i=0;i<h;i+=2)
|
{
|
k=i*(int)stride;
|
l=i*s/4;
|
//żÊýÐÐ
|
for (j=0;j<w;j+=2)
|
{
|
g=((unsigned int)(srcpixel[k+j*3/2]&0xff)<<4)+((unsigned int)(srcpixel[k+j*3/2+1]&0xf)); //
|
b=((unsigned int)(srcpixel[k+j*3/2+1]&0xf0)>>4)+(((unsigned int)srcpixel[k+j*3/2+2]&0xff)<<4);
|
r=((unsigned int)srcpixel[k+stride+j*3/2]<<4)+((unsigned int)(srcpixel[k+stride+j*3/2+1]&0xf));
|
//b=g;
|
//r=g;
|
c1.R=r>>4;
|
c1.G=g>>4;
|
c1.B=b>>4;
|
pixels[l+j]=c1.argb;
|
pixels[l+j+1]=c1.argb;
|
}
|
//ÆæÊýÐÐ
|
for (j=0;j<w;j+=2)
|
{
|
g=((unsigned int)(srcpixel[k+stride+j*3/2+2]&0xff)<<4)+((unsigned int)(srcpixel[k+stride+j*3/2+1]&0xf));
|
b=((unsigned int)(srcpixel[k+j*3/2+1]&0xf0)>>4)+((unsigned int)(srcpixel[k+j*3/2+2]&0xff)<<4);
|
r=((unsigned int)srcpixel[k+stride+j*3/2]<<4)+((unsigned int)(srcpixel[k+stride+j*3/2+1]&0xf));
|
c1.R=r>>4;
|
c1.G=g>>4;
|
c1.B=b>>4;
|
pixels[l+s/4+j]=c1.argb;
|
pixels[l+s/4+j+1]=c1.argb;
|
}
|
}
|
*/
|
double SysGamma=1.0f;
|
BayerGB12PackedToRGB32(pixels,srcpixel,w,h,(float)SysGamma);
|
}
|
(*bitmapdest)->UnlockBits(&bitmapdata1);
|
return 1;
|
}
|
|
int MyImage::ConvertThumbToGdipBitmap32(Gdiplus::Bitmap** bitmapdest, int Brightness, int Contrast)
|
{
|
/*
|
PixelType_Mono8
|
PixelType_BayerGB8
|
PixelType_BayerGB12
|
PixelType_YUV422packed
|
PixelType_YUV422_YUYV_Packed
|
PixelType_BayerGB12Packed
|
*/
|
int i, j, k, l;
|
int w, h;
|
w = m_thumbImg.nWidth;
|
h = m_thumbImg.nHeight;
|
int pixeltype;
|
pixeltype = this->PixelFormat;
|
|
if (*bitmapdest == NULL)
|
{
|
*bitmapdest = ::new Gdiplus::Bitmap(w, h);
|
}
|
else if ((*bitmapdest)->GetWidth() != w && (*bitmapdest)->GetHeight() != h)
|
{
|
::delete *bitmapdest; *bitmapdest = NULL;
|
*bitmapdest = ::new Gdiplus::Bitmap(w, h);
|
}
|
|
unsigned char * srcpixel = (unsigned char *)m_thumbImg.buffer;
|
Gdiplus::BitmapData bitmapdata1;
|
bitmapdata1.PixelFormat = PixelFormat32bppRGB;
|
Gdiplus::Rect rect1(0, 0, w, h);
|
Gdiplus::Status GdipStatus = (*bitmapdest)->LockBits(&rect1, Gdiplus::ImageLockModeWrite,//|ImageLockModeUserInputBuf,
|
PixelFormat32bppRGB, &bitmapdata1);//PixelFormat32bppRGB
|
if (GdipStatus != Gdiplus::Ok)
|
{
|
CString Errs1;
|
Errs1.Format(_T("Gdip LockBits Error %d \r\n"), GdipStatus);
|
// SysLog(Errs1);
|
return 0;
|
}
|
COLOR c1;
|
UINT * pixels;
|
pixels = (UINT *)bitmapdata1.Scan0;
|
int s = bitmapdata1.Stride;
|
|
|
if (pixeltype == MyPixelType_Mono8)
|
{
|
for (i = 0; i<h; i++)
|
{
|
k = i*(int)m_thumbImg.nWidth;
|
l = i*s / 4;
|
for (j = 0; j<w; j++)
|
{
|
c1.R = srcpixel[k + j];
|
c1.G = c1.R;
|
c1.B = c1.R;
|
c1.A = 255;
|
pixels[l + j] = c1.argb;
|
}
|
}
|
}
|
if (pixeltype == MyPixelType_ARGB32 || pixeltype == MyPixelType_RGB8planar)
|
{
|
memcpy(pixels, m_thumbImg.buffer, h*w * 4);
|
}
|
if (pixeltype == MyPixelType_BayerGR8)
|
{
|
BayerGR8toRGB32(m_thumbImg.buffer, bitmapdata1.Scan0, w, h, w, bitmapdata1.Stride);
|
}
|
if (pixeltype == MyPixelType_BayerGB8)
|
{
|
BayerGB8toRGB32(m_thumbImg.buffer, bitmapdata1.Scan0, w, h, w, bitmapdata1.Stride);
|
}
|
(*bitmapdest)->UnlockBits(&bitmapdata1);
|
return 1;
|
}
|
|
int GdipDrawRoundRect(Gdiplus::Graphics &gr1, Gdiplus::Pen &pen1, int x1, int y1, int x2, int y2, int r)
|
{
|
gr1.DrawLine(&pen1,x1+r,y1,x2-r,y1);
|
gr1.DrawLine(&pen1,x1+r,y2,x2-r,y2);
|
gr1.DrawLine(&pen1,x1,y1+r,x1,y2-r);
|
gr1.DrawLine(&pen1,x2,y1+r,x2,y2-r);
|
gr1.DrawArc(&pen1,x1,y1,r*2,r*2,180,90);
|
gr1.DrawArc(&pen1,x2-2*r,y1,r*2,r*2,270,90);
|
gr1.DrawArc(&pen1,x1,y2-r*2,r*2,r*2,90,90);
|
gr1.DrawArc(&pen1,x2-r*2,y2-r*2,r*2,r*2,0,90);
|
return 1;
|
}
|
|
int SaveBufferToFile(void * pBuf, size_t nSize, CString sFilePathName)
|
{
|
CString sFilePath;
|
int j;
|
j = sFilePathName.ReverseFind(_T('\\'));
|
sFilePath = sFilePathName.Left(j);
|
SHCreateDirectoryEx(NULL, sFilePath, NULL);
|
CFile file1;
|
CFileException e1;
|
j = file1.Open(sFilePathName, CFile::modeWrite | CFile::modeCreate, NULL, &e1);
|
if (!j) { return 0; }
|
file1.Write(pBuf, nSize);
|
file1.Close();
|
return 1;
|
}
|
|
int SaveBufferToBmpFile(void * buf1,int width, int height, int stride, CString FilePathName,LONG XPelsPerMeter,LONG YPelsPerMeter)
|
{
|
//·Ö½âÎļþ·¾¶ºÍÎļþÃû
|
CString sFilePath;
|
int j;
|
j=FilePathName.ReverseFind(_T('\\'));
|
sFilePath=FilePathName.Left(j);
|
//¼ì²éÊÇ·ñÓпÉÓõĴÅÅÌ¿Õ¼ä
|
ULARGE_INTEGER luse;
|
ULARGE_INTEGER ltotal;
|
ULARGE_INTEGER lfree;
|
|
double fuse,ftotal,ffree;
|
GetDiskFreeSpaceEx(sFilePath,&luse,<otal,&lfree);
|
fuse=luse.QuadPart/1024.0/1024.0/1024.0;
|
ftotal=ltotal.QuadPart/1048576.0/1024.0;
|
ffree=lfree.QuadPart/1048576.0/1024.0;
|
if (fuse<1.0) {return false;} //Èç¹û¿ÉÓÿռäСÓÚ1G£¬ÄÇô²»´æ´¢Îļþ¡£
|
//´´½¨Ä¿Â¼
|
SHCreateDirectoryEx(NULL,sFilePath,NULL);
|
|
//¿ªÊ¼´´½¨Î»Í¼Îļþ
|
long newStride;
|
newStride=((width+3)&0xfffc);
|
BITMAPFILEHEADER header1;
|
// BITMAPINFO info1;
|
BITMAPINFOHEADER infoheader1;
|
// RGBQUAD buf[256];
|
header1.bfType=0x4d42;
|
header1.bfSize=newStride*height+1078;
|
header1.bfReserved1=0;
|
header1.bfReserved2=0;
|
header1.bfOffBits=1078;
|
|
infoheader1.biSize=40;
|
infoheader1.biWidth=width;
|
infoheader1.biHeight=height;
|
infoheader1.biPlanes=1;
|
infoheader1.biBitCount=8;
|
infoheader1.biCompression=BI_RGB;
|
infoheader1.biSizeImage=0;
|
infoheader1.biXPelsPerMeter=XPelsPerMeter;
|
infoheader1.biYPelsPerMeter=YPelsPerMeter;
|
infoheader1.biClrUsed=0;
|
infoheader1.biClrImportant=0;
|
RGBQUAD pallette[256];
|
|
for (int i=0;i<256;i++)
|
{
|
pallette[i].rgbBlue=i;
|
pallette[i].rgbGreen=i;
|
pallette[i].rgbRed=i;
|
pallette[i].rgbReserved=0;
|
}
|
|
CFile file1;
|
CFileException e1;
|
j=file1.Open(FilePathName,CFile::modeWrite|CFile::modeCreate,NULL,&e1);
|
if (!j) {return 0;}
|
file1.Write(&header1,sizeof(header1));
|
file1.Write(&infoheader1,sizeof(infoheader1));
|
file1.Write(pallette,1024);
|
for (int i=0;i<height;i++)
|
{
|
file1.Write((char *)buf1+(height-i-1)*stride,newStride);
|
}
|
file1.Close();
|
return true;
|
}
|
|
int DrawBitmapOnWindow(HWND DestWindow,Bitmap* srcbitmap,CString * Lable, CString * ResultStr, double scale)
|
{
|
if (srcbitmap==NULL) return 0;
|
if (DestWindow==NULL) return 0;
|
if (!IsWindow(DestWindow)) return 0;
|
if (!IsWindowVisible(DestWindow)) return 0;
|
|
int srcw,srch;
|
srcw=srcbitmap->GetWidth();
|
srch=srcbitmap->GetHeight();
|
|
HDC hdc1=GetDC(DestWindow);
|
Graphics gr1(hdc1);
|
RECT rect0;
|
GetClientRect(DestWindow,&rect0);
|
int clientw,clienth; //¿Í»§Çøʵ¼ÊµÄ¿í¶ÈºÍ¸ß¶È
|
clientw=rect0.right-rect0.left;
|
clienth=rect0.bottom-rect0.top;
|
|
|
int w1,h1; //ͼƬÔÚ¿Í»§ÇøÏÔʾʱµÄ¿í¶ÈºÍ¸ß¶È,
|
//¿¼Âǵ½±£³Ö¿í¸ß±È£¬Óë¿Í»§Çø´óС²»Ò»¶¨Ïàͬ
|
int startx,starty;
|
//ͼƬÔÚ¿Í»§ÇøµÄÆðʼλÖÃ;
|
|
if (srcw*rect0.bottom==srch*rect0.right)
|
{
|
w1=clientw;
|
h1=clienth;
|
startx=rect0.left;
|
starty=rect0.top;
|
|
}else if (srcw*rect0.bottom>srch*rect0.right) //ͼƬºáÏò´ó£¬¸ß¶È²»Âú
|
{
|
w1=clientw;
|
h1=clientw*srch/srcw;
|
startx=rect0.left;
|
starty=rect0.top+(clienth-h1)/2;
|
}
|
else //ͼƬ×ÝÏò´ó,¿í¶È²»Âú
|
{
|
w1=clienth*srcw/srch;
|
h1=clienth;
|
startx=rect0.left+(clientw-w1)/2;
|
starty=rect0.top;
|
}
|
Rect rect1;
|
rect1.X=startx;
|
rect1.Y=starty;
|
rect1.Width=w1;
|
rect1.Height=h1;
|
|
SolidBrush brush1(Color(255,0,0,0)); //дºÚ×Ö
|
SolidBrush brush2(Color(255,255,255,255)); //д°××Ö
|
|
gr1.DrawImage(srcbitmap,rect1); //»Í¼Ïñ
|
if (startx!=0) //ÔÚͼÏñµÄÁ½²à»±³¾°
|
{
|
gr1.FillRectangle(&brush1,0,0,startx,clienth);
|
gr1.FillRectangle(&brush1,startx+w1,0,startx,clienth);
|
}
|
if (starty!=0)
|
{
|
gr1.FillRectangle(&brush1,0,0,clientw,starty);
|
gr1.FillRectangle(&brush1,0,starty+h1,clientw,starty);
|
}
|
///*
|
if (Lable!=NULL&&!Lable->IsEmpty())
|
{
|
CStringW sw1;
|
TToW(*Lable,sw1);
|
// Pen pen1(Color(255,0,0,0),1); //»ºÚÏß
|
Pen pen2(Color(128,128,128,128),0.5); //»»ÒÏß
|
|
FontFamily fontfamily1(L"ºÚÌå");
|
int fontsize=h1/60;
|
if (fontsize<16) {fontsize=16;}
|
Gdiplus::Font font1(&fontfamily1,fontsize,FontStyleRegular);
|
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
StringFormat stringformat1;
|
stringformat1.SetAlignment(StringAlignmentNear);
|
stringformat1.SetLineAlignment(StringAlignmentNear);
|
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+0.0f,starty+0.0f),&stringformat1,&brush1);
|
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+2.0f,starty+2.0f),&stringformat1,&brush1);
|
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+0.0f,starty+2.0f),&stringformat1,&brush1);
|
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+2.0f,starty+0.0f),&stringformat1,&brush1);
|
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+1.0f,starty+1.0f),&stringformat1,&brush2);
|
}
|
if (ResultStr!=NULL&&!ResultStr->IsEmpty())
|
{
|
CStringW sw1;
|
TToW(*ResultStr,sw1);
|
// Pen pen1(Color(255,0,0,0),1); //»ºÚÏß
|
Pen pen2(Color(128,128,128,128),0.5); //»»ÒÏß
|
SolidBrush brush3(Color(255,0,0,0)); //дºÚ×Ö
|
SolidBrush brush4(Color(128,0,255,0)); //дÂÌ×Ö
|
|
FontFamily fontfamily1(L"ºÚÌå");
|
int fontsize=h1/4;
|
if (fontsize<48) {fontsize=48;}
|
Gdiplus::Font font1(&fontfamily1,fontsize,FontStyleRegular);
|
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
StringFormat stringformat1;
|
stringformat1.SetAlignment(StringAlignmentCenter);
|
stringformat1.SetLineAlignment(StringAlignmentCenter);
|
float centerx,centery;
|
centerx=(rect0.right+rect0.left)/2;
|
centery=(rect0.top+rect0.bottom)/2;
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+0.0f),&stringformat1,&brush3);
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+2.0f),&stringformat1,&brush3);
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+2.0f),&stringformat1,&brush3);
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+0.0f),&stringformat1,&brush3);
|
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+1.0f,centery+1.0f),&stringformat1,&brush4);
|
}
|
// gr1.Flush();
|
//*/
|
ReleaseDC(DestWindow,hdc1);
|
return 0;
|
}
|
int DrawImageOnWindow(HWND DestWindow, Image* srcimage, CString * Lable, CString * ResultStr, double scale)
|
{
|
if (srcimage == NULL) return 0;
|
if (DestWindow == NULL) return 0;
|
if (!IsWindow(DestWindow)) return 0;
|
if (!IsWindowVisible(DestWindow)) return 0;
|
|
int srcw, srch;
|
srcw = srcimage->GetWidth();
|
srch = srcimage->GetHeight();
|
|
HDC hdc1 = GetDC(DestWindow);
|
Graphics gr1(hdc1);
|
RECT rect0;
|
GetClientRect(DestWindow, &rect0);
|
int clientw, clienth; //¿Í»§Çøʵ¼ÊµÄ¿í¶ÈºÍ¸ß¶È
|
clientw = rect0.right - rect0.left;
|
clienth = rect0.bottom - rect0.top;
|
|
|
int w1, h1; //ͼƬÔÚ¿Í»§ÇøÏÔʾʱµÄ¿í¶ÈºÍ¸ß¶È,
|
//¿¼Âǵ½±£³Ö¿í¸ß±È£¬Óë¿Í»§Çø´óС²»Ò»¶¨Ïàͬ
|
int startx, starty;
|
//ͼƬÔÚ¿Í»§ÇøµÄÆðʼλÖÃ;
|
|
if (srcw*rect0.bottom == srch*rect0.right)
|
{
|
w1 = clientw;
|
h1 = clienth;
|
startx = rect0.left;
|
starty = rect0.top;
|
|
}
|
else if (srcw*rect0.bottom>srch*rect0.right) //ͼƬºáÏò´ó£¬¸ß¶È²»Âú
|
{
|
w1 = clientw;
|
h1 = clientw*srch / srcw;
|
startx = rect0.left;
|
starty = rect0.top + (clienth - h1) / 2;
|
}
|
else //ͼƬ×ÝÏò´ó,¿í¶È²»Âú
|
{
|
w1 = clienth*srcw / srch;
|
h1 = clienth;
|
startx = rect0.left + (clientw - w1) / 2;
|
starty = rect0.top;
|
}
|
Rect rect1;
|
rect1.X = startx;
|
rect1.Y = starty;
|
rect1.Width = w1;
|
rect1.Height = h1;
|
|
SolidBrush brush1(Color(255, 0, 0, 0)); //дºÚ×Ö
|
SolidBrush brush2(Color(255, 255, 255, 255)); //д°××Ö
|
|
gr1.DrawImage(srcimage, rect1); //»Í¼Ïñ
|
if (startx != 0) //ÔÚͼÏñµÄÁ½²à»±³¾°
|
{
|
gr1.FillRectangle(&brush1, 0, 0, startx, clienth);
|
gr1.FillRectangle(&brush1, startx + w1, 0, startx, clienth);
|
}
|
if (starty != 0)
|
{
|
gr1.FillRectangle(&brush1, 0, 0, clientw, starty);
|
gr1.FillRectangle(&brush1, 0, starty + h1, clientw, starty);
|
}
|
|
if (Lable != NULL&&!Lable->IsEmpty())
|
{
|
CStringW sw1;
|
TToW(*Lable, sw1);
|
// Pen pen1(Color(255,0,0,0),1); //»ºÚÏß
|
Pen pen2(Color(128, 128, 128, 128), 0.5); //»»ÒÏß
|
|
FontFamily fontfamily1(L"ºÚÌå");
|
int fontsize = h1 / 60;
|
if (fontsize<16) { fontsize = 16; }
|
Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
|
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
StringFormat stringformat1;
|
stringformat1.SetAlignment(StringAlignmentNear);
|
stringformat1.SetLineAlignment(StringAlignmentNear);
|
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 0.0f, starty + 0.0f), &stringformat1, &brush1);
|
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 2.0f, starty + 2.0f), &stringformat1, &brush1);
|
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 0.0f, starty + 2.0f), &stringformat1, &brush1);
|
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 2.0f, starty + 0.0f), &stringformat1, &brush1);
|
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 1.0f, starty + 1.0f), &stringformat1, &brush2);
|
}
|
if (ResultStr != NULL&&!ResultStr->IsEmpty())
|
{
|
CStringW sw1;
|
TToW(*ResultStr, sw1);
|
// Pen pen1(Color(255,0,0,0),1); //»ºÚÏß
|
Pen pen2(Color(128, 128, 128, 128), 0.5); //»»ÒÏß
|
SolidBrush brush3(Color(255, 0, 0, 0)); //дºÚ×Ö
|
SolidBrush brush4(Color(128, 0, 255, 0)); //дÂÌ×Ö
|
|
FontFamily fontfamily1(L"ºÚÌå");
|
int fontsize = h1 / 4;
|
if (fontsize<48) { fontsize = 48; }
|
Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
|
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
StringFormat stringformat1;
|
stringformat1.SetAlignment(StringAlignmentCenter);
|
stringformat1.SetLineAlignment(StringAlignmentCenter);
|
float centerx, centery;
|
centerx = (rect0.right + rect0.left) / 2;
|
centery = (rect0.top + rect0.bottom) / 2;
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+0.0f),&stringformat1,&brush3);
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+2.0f),&stringformat1,&brush3);
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+2.0f),&stringformat1,&brush3);
|
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+0.0f),&stringformat1,&brush3);
|
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(centerx + 1.0f, centery + 1.0f), &stringformat1, &brush4);
|
}
|
// gr1.Flush();
|
ReleaseDC(DestWindow, hdc1);
|
return 0;
|
}
|
|
int LoadImageFromBuffer(void *pBuffer, ULONGLONG sizeImage, Gdiplus::Image ** ppimage1)
|
{
|
HGLOBAL hBuffer;
|
hBuffer = GlobalAlloc(GMEM_MOVEABLE, sizeImage);
|
if (hBuffer == NULL)
|
{
|
//s1.Format(_T("·ÖÅäÄÚ´æʧ°Ü \r\n")); MyLogger1.LogTxt(s1);
|
return 0;
|
}
|
// s1.Format(_T("·ÖÅäÄÚ´æ³É¹¦ HGlobal %x\r\n"), hBuffer); MyLogger1.LogTxt(s1);
|
|
LPVOID pImageData = ::GlobalLock(hBuffer);
|
if (pImageData == NULL)
|
{
|
//s1.Format(_T("Ëø¶¨ÄÚ´æʧ°Ü\r\n")); MyLogger1.LogTxt(s1);
|
::GlobalFree(hBuffer);
|
return 0;
|
}
|
//s1.Format(_T("Ëø¶¨ÄÚ´æ³É¹¦ HGlobal %p\r\n"), pImageData); MyLogger1.LogTxt(s1);
|
|
memcpy(pImageData, pBuffer, sizeImage);
|
::GlobalUnlock(hBuffer);
|
IStream *ps = NULL;
|
Gdiplus::Image *pImg = NULL;
|
if (::CreateStreamOnHGlobal(hBuffer, TRUE, &ps) == S_OK)
|
{
|
//s1.Format(_T("´´½¨Stream³É¹¦ \r\n")); MyLogger1.LogTxt(s1);
|
pImg = Gdiplus::Image::FromStream(ps);
|
if (pImg != NULL)
|
{
|
int w, h;
|
w = pImg->GetWidth();
|
h = pImg->GetHeight();
|
//s1.Format(_T("´´½¨Image³É¹¦ W %d h %d \r\n"), w, h); MyLogger1.LogTxt(s1);
|
}
|
//_SanUiGdiImageValid(pImg);
|
*ppimage1 = pImg;
|
ps->Release();
|
//::GlobalFree(hBuffer);
|
return 1;
|
}
|
return 1;
|
}
|
int HistoGram::MakeHistoGram(Gdiplus::Bitmap * bitmap, int startx, int starty, int width, int height)
|
{
|
int i,w,h;
|
if (width==0) { w=bitmap->GetWidth();}
|
else {w=width;}
|
if (height==0) {h=bitmap->GetHeight();}
|
else {h=height;}
|
|
totalpixels=0;
|
maxRsample=0;
|
maxRsampleindex=0;
|
maxGsample=0;
|
maxGsampleindex=0;
|
maxBsample=0;
|
maxBsampleindex=0;
|
maxVsample=0;
|
maxVsampleindex=0;
|
totalRvalues=0;
|
totalGvalues=0;
|
totalBvalues=0;
|
totalVvalues=0;
|
minRvalue=255;
|
maxRvalue=0;
|
minGvalue=255;
|
maxGvalue=0;
|
minBvalue=255;
|
maxBvalue=0;
|
minVvalue=255;
|
maxVvalue=0;
|
for (i=0;i<256;i++)
|
{
|
Rsamples[i]=0;
|
Gsamples[i]=0;
|
Bsamples[i]=0;
|
Vsamples[i]=0;
|
}
|
UINT * pixels;
|
COLOR c1;
|
// BYTE R,G,B;
|
BYTE V;
|
|
Gdiplus::BitmapData bitmapData0;
|
Gdiplus::Rect rect0(startx,starty,w,h);
|
Gdiplus::Status GdipStatus=bitmap->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapData0);
|
if (GdipStatus!=Gdiplus::Ok)
|
{
|
CString Errs1;
|
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
// SysLog(Errs1);
|
return 0;
|
}
|
// bitmap->UnlockBits(&bitmapData0);
|
// bitmap->LockBits(&rect0,ImageLockModeRead,PixelFormat32bppRGB,&bitmapData0);
|
pixels=(UINT *)bitmapData0.Scan0;
|
totalpixels=h*w;
|
int step;step=totalpixels/1048576;
|
if (step<1) {step=1;}
|
step=1;
|
int s=bitmapData0.Stride/4;
|
// int k;
|
for (i=0;i<h;i+=step)
|
{
|
int k=i*s;
|
for (int j=0;j<width;j++)
|
{
|
///*
|
c1.argb =pixels[k+j];
|
V=int(RGBtoVI(c1.R,c1.G,c1.B));
|
Rsamples[c1.R]++;
|
Gsamples[c1.G]++;
|
Bsamples[c1.B]++;
|
Vsamples[V]++;
|
}
|
}
|
bitmap->UnlockBits(&bitmapData0);
|
///*
|
totalpixels-=Vsamples[0];
|
Rsamples[0]=0;
|
Gsamples[0]=0;
|
Bsamples[0]=0;
|
Vsamples[0]=0;
|
for (i=0;i<256;i++)
|
{
|
totalRvalues+=Rsamples[i]*i;
|
totalGvalues+=Gsamples[i]*i;
|
totalBvalues+=Bsamples[i]*i;
|
totalVvalues+=Vsamples[i]*i;
|
if (Rsamples[i]>0)
|
{
|
if (i<minRvalue) {minRvalue=i;}
|
if (i>maxRvalue) {maxRvalue=i;}
|
if (Rsamples[i]>maxRsample) {maxRsample=Rsamples[i];maxRsampleindex=i;}
|
}
|
if (Gsamples[i]>0)
|
{
|
if (i<minGvalue) {minGvalue=i;}
|
if (i>maxGvalue) {maxGvalue=i;}
|
if (Gsamples[i]>maxGsample) {maxGsample=Gsamples[i];maxGsampleindex=i;}
|
}
|
if (Bsamples[i]>0)
|
{
|
if (i<minBvalue) {minBvalue=i;}
|
if (i>maxBvalue) {maxBvalue=i;}
|
if (Bsamples[i]>maxBsample) {maxBsample=Bsamples[i];maxBsampleindex=i;}
|
}
|
if (Vsamples[i]>0)
|
{
|
if (i<minVvalue) {minVvalue=i;}
|
if (i>maxVvalue) {maxVvalue=i;}
|
if (Vsamples[i]>maxVsample) {maxVsample=Vsamples[i];maxVsampleindex=i;}
|
}
|
|
}
|
//*/
|
|
if (0==totalpixels) {totalpixels=1;}
|
aveRvalue=(float)totalRvalues/totalpixels;
|
aveGvalue=(float)totalGvalues/totalpixels;
|
aveBvalue=(float)totalBvalues/totalpixels;
|
aveVvalue=(float)totalVvalues/totalpixels;
|
|
if (maxRsample==0) {maxRsample=1;}
|
if (maxGsample==0) {maxGsample=1;}
|
if (maxBsample==0) {maxBsample=1;}
|
if (maxVsample==0) {maxVsample=1;}
|
|
return totalpixels;
|
};
|
// HISTOGRAM();
|
// HISTOGRAM(Bitmap * bitmap);
|
// HISTOGRAM(Bitmap * bitmap)
|
// {
|
// MakeHistoGram(bitmap);
|
// };
|
int HistoGram::getRpercentvalue(float percent)
|
{
|
int i,j;
|
j=0;
|
for (i=0;i<256;i++)
|
{
|
j+=Rsamples[i];
|
if (j>=percent*totalpixels) {break;}
|
}
|
return i;
|
}
|
|
|
int HistoGram::getGpercentvalue(float percent)
|
{
|
int i,j;
|
j=0;
|
for (i=0;i<256;i++)
|
{
|
j+=Gsamples[i];
|
if (j>=percent*totalpixels) {break;}
|
}
|
return i;
|
}
|
|
|
int HistoGram::getBpercentvalue(float percent)
|
{
|
int i,j;
|
j=0;
|
for (i=0;i<256;i++)
|
{
|
j+=Bsamples[i];
|
if (j>=percent*totalpixels) {break;}
|
}
|
return i;
|
}
|
|
int HistoGram::getVpercentvalue(float percent)
|
{
|
int i,j;
|
j=0;
|
for (i=0;i<256;i++)
|
{
|
j+=Vsamples[i];
|
if (j>=percent*totalpixels) {break;}
|
}
|
return i;
|
}
|
|
float HistoGram::GetMostRvalue()
|
{
|
float r;
|
int i;
|
i=maxRsampleindex;
|
if (i==0)
|
{
|
r=float(Rsamples[i]*i+Rsamples[i+1]*(i+1))/(Rsamples[i]+Rsamples[i+1]);
|
return r;
|
}
|
if (i==255)
|
{
|
r=float(Rsamples[i-1]*(i-1)+Rsamples[i]*(i))/(Rsamples[i-1]+Rsamples[i]);
|
return r;
|
}
|
if (Rsamples[i-1]>Rsamples[i+1])
|
{
|
int sample1,samplemax,sample2;
|
sample1=Rsamples[i-1];
|
samplemax=Rsamples[i];
|
sample2=Rsamples[i+1];
|
r=float(i)-float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
}
|
else
|
{
|
int sample1,samplemax,sample2;
|
sample2=Rsamples[i-1];
|
samplemax=Rsamples[i];
|
sample1=Rsamples[i+1];
|
r=float(i)+float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
|
}
|
//r=double(Rsamples[i-1]*(i-1)+Rsamples[i]*(i)+Rsamples[i+1]*(i+1))/(Rsamples[i-1]+Rsamples[i]+Rsamples[i+1]);
|
return r;
|
}
|
float HistoGram::GetMostGvalue()
|
{
|
float g;
|
int i;
|
i=maxGsampleindex;
|
if (i==0)
|
{
|
g=float(Gsamples[i]*i+Gsamples[i+1]*(i+1))/(Gsamples[i]+Gsamples[i+1]);
|
return g;
|
}
|
if (i==255)
|
{
|
g=float(Gsamples[i-1]*(i-1)+Gsamples[i]*(i))/(Gsamples[i-1]+Gsamples[i]);
|
return g;
|
}
|
if (Gsamples[i-1]>Gsamples[i+1])
|
{
|
int sample1,samplemax,sample2;
|
sample1=Gsamples[i-1];
|
samplemax=Gsamples[i];
|
sample2=Gsamples[i+1];
|
g=float(i)-float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
}
|
else
|
{
|
int sample1,samplemax,sample2;
|
sample2=Gsamples[i-1];
|
samplemax=Gsamples[i];
|
sample1=Gsamples[i+1];
|
g=float(i)+float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
|
}
|
// g=double(Gsamples[i-1]*(i-1)+Gsamples[i]*(i)+Gsamples[i+1]*(i+1))/(Gsamples[i-1]+Gsamples[i]+Gsamples[i+1]);
|
return g;
|
}
|
float HistoGram::GetMostBvalue()
|
{
|
float b;
|
int i;
|
i=maxBsampleindex;
|
if (i==0)
|
{
|
b=float(Bsamples[i]*i+Bsamples[i+1]*(i+1))/(Bsamples[i]+Bsamples[i+1]);
|
return b;
|
}
|
if (i==255)
|
{
|
b=float(Bsamples[i-1]*(i-1)+Bsamples[i]*(i))/(Bsamples[i-1]+Bsamples[i]);
|
return b;
|
}
|
if (Bsamples[i-1]>Bsamples[i+1])
|
{
|
int sample1,samplemax,sample2;
|
sample1=Bsamples[i-1];
|
samplemax=Bsamples[i];
|
sample2=Bsamples[i+1];
|
b=float(i)-float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
}
|
else
|
{
|
int sample1,samplemax,sample2;
|
sample2=Bsamples[i-1];
|
samplemax=Bsamples[i];
|
sample1=Bsamples[i+1];
|
b=float(i)+float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
|
}
|
|
b=float(Bsamples[i-1]*(i-1)+Bsamples[i]*(i)+Bsamples[i+1]*(i+1))/(Bsamples[i-1]+Bsamples[i]+Bsamples[i+1]);
|
return b;
|
}
|
|
int QuadRectTransForm(Gdiplus::Bitmap* bitmapsrc,POINT srcpt[4],Gdiplus::Bitmap * bitmapdest,Gdiplus::Rect destrect)
|
{
|
Gdiplus::PointF pt[4];
|
for (int i=0;i<4;i++)
|
{
|
pt[i].X=float(srcpt[i].x);pt[i].Y=float(srcpt[i].y);
|
}
|
return QuadRectTransForm(bitmapsrc,pt,bitmapdest,destrect);
|
}
|
int QuadRectTransForm(Gdiplus::Bitmap* bitmapsrc,Gdiplus::Point srcpt[4],Gdiplus::Bitmap * bitmapdest,Gdiplus::Rect destrect)
|
{
|
Gdiplus::PointF pt[4];
|
for (int i=0;i<4;i++)
|
{
|
pt[i].X=float(srcpt[i].X);pt[i].Y=float(srcpt[i].X);
|
}
|
return QuadRectTransForm(bitmapsrc,pt,bitmapdest,destrect);
|
return 1;
|
}
|
|
UINT __cdecl TransFormThread(LPVOID pParam)
|
{
|
TransFormThreadDataStruct * mydata=(TransFormThreadDataStruct *)pParam;
|
int w,h;
|
w=mydata->destrect.Width;
|
h=mydata->destrect.Height;
|
|
Gdiplus::PointF startpt,endpt,curpt;
|
|
Gdiplus::PointF leftdelta,rightDelta;
|
Gdiplus::PointF leftstart,rightstart;
|
Gdiplus::PointF curstart,curdelta;
|
int i,j,k,l;
|
|
int curx,cury; //×îÁÙ½üµÄÏñËØ? ×óÉϽǵÄÏñËØ
|
COLORf c1f;
|
COLOR c1;
|
COLOR src[2][2];
|
float jitx,jity,remainx,remainy;
|
UINT * myDestPixels=mydata->destpixels;
|
int myno=mydata->ThreadNo;
|
double time1=GetTickCountmS();
|
for (i=mydata->starth;i<mydata->endh;i++)
|
{
|
|
startpt.X=(mydata->srcpt[0].X*(h-i)+mydata->srcpt[3].X*(i))/(float)h;
|
startpt.Y=(mydata->srcpt[0].Y*(h-i)+mydata->srcpt[3].Y*(i))/(float)h;
|
|
endpt.X=(mydata->srcpt[1].X*(h-i)+mydata->srcpt[2].X*(i))/(float)h;
|
endpt.Y=(mydata->srcpt[1].Y*(h-i)+mydata->srcpt[2].Y*(i))/(float)h;
|
|
|
l=i*mydata->deststride;
|
for (j=0;j<w;j++)
|
{
|
curpt.X=(startpt.X*(w-j)+endpt.X*(j))/w;
|
curpt.Y=(startpt.Y*(w-j)+endpt.Y*(j))/w;
|
curx=int(curpt.X); cury=int(curpt.Y);
|
if (curx<0||curx>=mydata->srcw-1) {continue;}
|
if (cury<0||cury>=mydata->srch-1) {continue;}
|
jitx=curpt.X-curx; jity=curpt.Y-cury; //Ë«ÏßÐÔ²åÖµ
|
remainx=1.0f-jitx; remainy=1.0f-jity;
|
double remainxremainy=remainx*remainy;
|
double jitxremainy=jitx*remainy;
|
double remainxjity=remainx*jity;
|
double jitxjity=jitx*jity;
|
k=cury*mydata->srcstride;
|
src[0][0].argb = mydata->srcpixels[k+curx];
|
src[0][1].argb = mydata->srcpixels[k+curx+1];
|
src[1][0].argb = mydata->srcpixels[k+mydata->srcstride+curx];
|
src[1][1].argb = mydata->srcpixels[k+mydata->srcstride+curx+1];
|
|
c1f.R=float( src[0][0].R*remainxremainy+src[0][1].R*jitxremainy+src[1][0].R*remainxjity+src[1][1].R*jitxjity);
|
c1f.G=float( src[0][0].G*remainxremainy+src[0][1].G*jitxremainy+src[1][0].G*remainxjity+src[1][1].G*jitxjity);
|
c1f.B=float( src[0][0].B*remainxremainy+src[0][1].B*jitxremainy+src[1][0].B*remainxjity+src[1][1].B*jitxjity);
|
|
c1.R=int(c1f.R); c1.G=int(c1f.G); c1.B=int(c1f.B);c1.A=255;
|
myDestPixels[l+j]=c1.argb;
|
|
//srcpixels[cury*srcstride+curx]; //×îÁÚ½üÏñËØÈ¡Öµ
|
}
|
}
|
double time2=GetTickCountmS();
|
double time3=time2-time1;
|
mydata->Done=1;
|
return 1000+myno;
|
};
|
int QuadRectTransForm(Gdiplus::Bitmap* bitmapsrc,Gdiplus::PointF srcpt[4],Gdiplus::Bitmap * bitmapdest,Gdiplus::Rect destrect)
|
{
|
Gdiplus::BitmapData bitmapdatasrc;
|
Gdiplus::BitmapData bitmapdatadest;
|
int srcw,srch;
|
if (bitmapsrc==NULL) {return -1;}
|
srcw=bitmapsrc->GetWidth();
|
srch=bitmapsrc->GetHeight();
|
Gdiplus::Rect rect1(0,0,srcw,srch);
|
Gdiplus::Status sta1,sta2;
|
sta1=bitmapsrc->LockBits(&rect1,Gdiplus::ImageLockModeRead,PixelFormat32bppARGB,&bitmapdatasrc);
|
if (sta1!=Gdiplus::Ok)
|
{
|
return -1;
|
}
|
sta2=bitmapdest->LockBits(&destrect,Gdiplus::ImageLockModeWrite,PixelFormat32bppARGB,&bitmapdatadest);
|
if (sta2!=Gdiplus::Ok)
|
{
|
return -1;
|
}
|
UINT *srcpixels=(UINT *)bitmapdatasrc.Scan0;
|
int srcstride=bitmapdatasrc.Stride/4;;
|
UINT *destpixels=(UINT *)bitmapdatadest.Scan0;
|
int deststride=bitmapdatadest.Stride/4;
|
int w,h;
|
w=destrect.Width;
|
h=destrect.Height;
|
#define ThreadCount 2
|
TransFormThreadDataStruct TransFromThreadData[ThreadCount];
|
for (int i=0;i<ThreadCount;i++)
|
{
|
TransFromThreadData[i].ThreadNo=i;
|
TransFromThreadData[i].Done=0;
|
TransFromThreadData[i].srcpixels=srcpixels;
|
TransFromThreadData[i].srcstride=srcstride;
|
TransFromThreadData[i].destpixels=destpixels;
|
TransFromThreadData[i].deststride=deststride;
|
TransFromThreadData[i].srcw=srcw;
|
TransFromThreadData[i].srch=srch;
|
TransFromThreadData[i].srcpt[0]=srcpt[0];
|
TransFromThreadData[i].srcpt[1]=srcpt[1];
|
TransFromThreadData[i].srcpt[2]=srcpt[2];
|
TransFromThreadData[i].srcpt[3]=srcpt[3];
|
TransFromThreadData[i].destrect=destrect;
|
TransFromThreadData[i].starth=i*h/ThreadCount;
|
TransFromThreadData[i].endh=(i+1)*h/ThreadCount;
|
}
|
|
CWinThread * threads[ThreadCount];
|
HANDLE hthreads[ThreadCount];
|
CString s1;
|
DWORD dwerr;
|
// CWinThread thread1(TransFormThread,(LPVOID)(&TransFromThreadData[0]));
|
// CWinThread thread2(TransFormThread,(LPVOID)(&TransFromThreadData[0]));
|
for (int i=0;i<ThreadCount;i++)
|
{
|
threads[i]=AfxBeginThread(TransFormThread,(LPVOID)(&TransFromThreadData[i]),0,8192);
|
if (threads[i]!=NULL)
|
{
|
hthreads[i]=threads[i]->m_hThread;
|
}
|
else
|
{
|
dwerr=GetLastError();
|
s1.Format(_T("BeginThread %d fail %d \r\n"),i,dwerr);
|
// SysLog(s1);
|
}
|
}
|
// DWORD iRet;
|
// iRet=WaitForMultipleObjects(ThreadCount,hthreads,true,3000);
|
|
while(1)
|
{
|
int jumpout=1;
|
for (int i=0;i<ThreadCount;i++)
|
{
|
if (TransFromThreadData[i].Done==0) jumpout=0;
|
}
|
if (jumpout) break;
|
Sleep(10);
|
};
|
|
/*
|
PointF startpt,endpt,curpt;
|
|
PointF leftdelta,rightDelta;
|
PointF leftstart,rightstart;
|
PointF curstart,curdelta;
|
int i,j;//,k,l;
|
|
int curx,cury; //×îÁÙ½üµÄÏñËØ? ×óÉϽǵÄÏñËØ
|
COLORf c1f;
|
COLOR c1;
|
COLOR src[2][2];
|
float jitx,jity,remainx,remainy;
|
|
|
|
for (i=0;i<h;i++)
|
{
|
|
startpt.X=(srcpt[0].X*(h-i)+srcpt[3].X*(i))/(float)h;
|
startpt.Y=(srcpt[0].Y*(h-i)+srcpt[3].Y*(i))/(float)h;
|
|
endpt.X=(srcpt[1].X*(h-i)+srcpt[2].X*(i))/(float)h;
|
endpt.Y=(srcpt[1].Y*(h-i)+srcpt[2].Y*(i))/(float)h;
|
|
|
for (j=0;j<w;j++)
|
{
|
curpt.X=(startpt.X*(w-j)+endpt.X*(j))/w;
|
curpt.Y=(startpt.Y*(w-j)+endpt.Y*(j))/w;
|
curx=int(curpt.X); cury=int(curpt.Y);
|
if (curx<0||curx>=srcw-1) {continue;}
|
if (cury<0||cury>=srch-1) {continue;}
|
jitx=curpt.X-curx; jity=curpt.Y-cury; //Ë«ÏßÐÔ²åÖµ
|
remainx=1.0f-jitx; remainy=1.0f-jity;
|
double remainxremainy=remainx*remainy;
|
double jitxremainy=jitx*remainy;
|
double remainxjity=remainx*jity;
|
double jitxjity=jitx*jity;
|
src[0][0].argb = srcpixels[cury*srcstride+curx];
|
src[0][1].argb = srcpixels[cury*srcstride+curx+1];
|
src[1][0].argb = srcpixels[(cury+1)*srcstride+curx];
|
src[1][1].argb = srcpixels[(cury+1)*srcstride+curx+1];
|
//c1f.R= src[0][0].R*remainx*remainy+src[0][1].R*jitx*remainy+src[1][0].R*remainx*jity+src[1][1].R*jitx*jity;
|
//c1f.G= src[0][0].G*remainx*remainy+src[0][1].G*jitx*remainy+src[1][0].G*remainx*jity+src[1][1].G*jitx*jity;
|
//c1f.B= src[0][0].B*remainx*remainy+src[0][1].B*jitx*remainy+src[1][0].B*remainx*jity+src[1][1].B*jitx*jity;
|
c1f.R= src[0][0].R*remainxremainy+src[0][1].R*jitxremainy+src[1][0].R*remainxjity+src[1][1].R*jitxjity;
|
c1f.G= src[0][0].G*remainxremainy+src[0][1].G*jitxremainy+src[1][0].G*remainxjity+src[1][1].G*jitxjity;
|
c1f.B= src[0][0].B*remainxremainy+src[0][1].B*jitxremainy+src[1][0].B*remainxjity+src[1][1].B*jitxjity;
|
|
c1.R=int(c1f.R); c1.G=int(c1f.G); c1.B=int(c1f.B);c1.A=255;
|
destpixels[i*deststride+j]=c1.argb;
|
|
//srcpixels[cury*srcstride+curx]; //×îÁÚ½üÏñËØÈ¡Öµ
|
}
|
}
|
*/
|
bitmapdest->UnlockBits(&bitmapdatadest);
|
bitmapsrc->UnlockBits(&bitmapdatasrc);
|
return 1;
|
}
|
|
|
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
|
{
|
UINT num = 0; // number of image encoders
|
UINT size = 0; // size of the image encoder array in bytes
|
|
Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
|
|
Gdiplus::GetImageEncodersSize(&num, &size);
|
if(size == 0)
|
return -1; // Failure
|
|
pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
|
if(pImageCodecInfo == NULL)
|
return -1; // Failure
|
|
Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);
|
|
for(UINT j = 0; j < num; ++j)
|
{
|
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
|
{
|
*pClsid = pImageCodecInfo[j].Clsid;
|
free(pImageCodecInfo);
|
return j; // Success
|
}
|
}
|
|
free(pImageCodecInfo);
|
return -1; // Failure
|
}
|
int SaveGdiPImageAsFile(Gdiplus::Bitmap * bitmap1, CString sFileName, double Ratio,int Quality)
|
{
|
|
// double tick0=GetTickCountmS();
|
CString s1;
|
int w,h;
|
if (Ratio==0) {Ratio=1;}
|
if (bitmap1==NULL)
|
{
|
s1.Format(_T("ԴͼÏñΪ¿Õ£¬²»Äܱ£´æ\r\n"));
|
// SysLog(s1);
|
return 0;
|
}
|
if (bitmap1->GetWidth()==0||bitmap1->GetHeight()==0)
|
{
|
s1.Format(_T("ԴͼÏñΪ¿Õ£¬²»Äܱ£´æ\r\n"));
|
// SysLog(s1);
|
return 0;
|
}
|
CString sFilePath;
|
sFilePath=sFileName.Left(sFileName.ReverseFind(_T('\\')));
|
//¼ì²éÊÇ·ñÓпÉÓõĴÅÅÌ¿Õ¼ä
|
ULARGE_INTEGER luse;
|
ULARGE_INTEGER ltotal;
|
ULARGE_INTEGER lfree;
|
|
double fuse,ftotal,ffree;
|
GetDiskFreeSpaceEx(sFilePath,&luse,<otal,&lfree);
|
fuse=luse.QuadPart/1024.0/1024.0/1024.0;
|
ftotal=ltotal.QuadPart/1048576.0/1024.0;
|
ffree=lfree.QuadPart/1048576.0/1024.0;
|
if (fuse<2.0) {return 0;} //Èç¹û¿ÉÓÿռäСÓÚ2G£¬ÄÇô²»´æ´¢Îļþ¡£
|
//´´½¨Ä¿Â¼
|
SHCreateDirectoryEx(NULL,sFilePath,NULL);
|
//´´½¨BMPÎļþ
|
w=int(bitmap1->GetWidth()*Ratio+0.5);
|
h=int(bitmap1->GetHeight()*Ratio+0.5);
|
Gdiplus::Bitmap bitmapsave(w,h,PixelFormat24bppRGB);
|
Gdiplus::Graphics graphic3(&bitmapsave);
|
graphic3.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
|
graphic3.DrawImage(bitmap1,Gdiplus::Rect(0,0,w,h),0,0,bitmap1->GetWidth(),bitmap1->GetHeight(),Gdiplus::UnitPixel); //±ÈÀýËõ·Å
|
CLSID bmpClsid;
|
CLSID gifClsid;
|
CLSID pngClsid;
|
CLSID jpegClsid;
|
CLSID tifClsid;
|
GetEncoderClsid(L"image/bmp", &bmpClsid);
|
GetEncoderClsid(L"image/jpeg", &jpegClsid);
|
GetEncoderClsid(L"image/gif", &gifClsid);
|
GetEncoderClsid(L"image/tiff", &tifClsid);
|
GetEncoderClsid(L"image/png", &pngClsid);
|
// int i,j;
|
// CString s1;
|
CStringW sw1;
|
CString s2;
|
//FilePathName=Prsfilepath+_T("\\")+savedfilename;
|
s1=sFileName;
|
|
// ::SysLog(s1);
|
// wcscpy_s(wbuf1,1000,ToWChar(s1.GetBuffer(100)));
|
ULONG picquality=Quality;
|
Gdiplus::EncoderParameters * pparas1 = (Gdiplus::EncoderParameters *) new byte[sizeof(EncoderParameters) + sizeof(EncoderParameter)];
|
|
pparas1->Count=1;
|
pparas1->Parameter[0].Guid=Gdiplus::EncoderQuality;
|
pparas1->Parameter[0].Type=Gdiplus::EncoderParameterValueTypeLong;
|
pparas1->Parameter[0].NumberOfValues=1;
|
pparas1->Parameter[0].Value=&picquality;
|
|
//pparas1->Count = 2;
|
//ULONG value2 = EncoderValueCompressionLZW;
|
//pparas1->Parameter[1].Guid = Gdiplus::EncoderCompression;
|
//pparas1->Parameter[1].Type = Gdiplus::EncoderParameterValueTypeLong;
|
//pparas1->Parameter[1].NumberOfValues = 1;
|
//pparas1->Parameter[1].Value = &value2;
|
|
#ifdef UNICODE
|
sw1.Format(L"%s",s1);
|
#else
|
WCHAR wbuf1[1000];
|
wcscpy_s(wbuf1,1000,ToWChar(s1.GetBuffer(100)));
|
sw1.Format(L"%s",wbuf1);
|
#endif
|
if (sw1.Find(L".BMP") > 0)
|
{
|
bitmapsave.Save(sw1, &bmpClsid, pparas1);
|
}
|
else if (sw1.Find(L".JPG") > 0)
|
{
|
bitmapsave.Save(sw1, &jpegClsid, pparas1);
|
}
|
else if (sw1.Find(L".GIF") > 0)
|
{
|
bitmapsave.Save(sw1, &gifClsid, pparas1);
|
}
|
else if (sw1.Find(L".TIF") > 0)
|
{
|
bitmapsave.Save(sw1, &tifClsid, pparas1);
|
}
|
else if (sw1.Find(L".PNG") > 0)
|
{
|
bitmapsave.Save(sw1, &pngClsid, pparas1);
|
}
|
else
|
{
|
bitmapsave.Save(sw1, &bmpClsid, pparas1);
|
}
|
// double tick1=GetTickCountmS();
|
delete[] pparas1;
|
return 1;
|
|
}
|
int SaveGdiPImageAsBuffer(Gdiplus::Image * image1, void ** ppBuffer, ULONGLONG *psizeImage, double Ratio, int Quality)
|
{
|
|
// double tick0=GetTickCountmS();
|
CString s1;
|
int w, h;
|
if (Ratio == 0) { Ratio = 1; }
|
if (image1 == NULL)
|
{
|
s1.Format(_T("ԴͼÏñΪ¿Õ£¬²»Äܱ£´æ\r\n"));
|
// SysLog(s1);
|
return 0;
|
}
|
|
w = int(image1->GetWidth()*Ratio + 0.5);
|
h = int(image1->GetHeight()*Ratio + 0.5);
|
Gdiplus::Bitmap bitmapsave(w, h, PixelFormat24bppRGB);
|
Gdiplus::Graphics graphic3(&bitmapsave);
|
graphic3.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
|
graphic3.DrawImage(image1, Gdiplus::Rect(0, 0, w, h), 0, 0, image1->GetWidth(), image1->GetHeight(), Gdiplus::UnitPixel); //±ÈÀýËõ·Å
|
CLSID bmpClsid;
|
CLSID gifClsid;
|
CLSID pngClsid;
|
CLSID jpegClsid;
|
CLSID tifClsid;
|
GetEncoderClsid(L"image/bmp", &bmpClsid);
|
GetEncoderClsid(L"image/jpeg", &jpegClsid);
|
GetEncoderClsid(L"image/gif", &gifClsid);
|
GetEncoderClsid(L"image/tiff", &tifClsid);
|
GetEncoderClsid(L"image/png", &pngClsid);
|
// int i,j;
|
// CString s1;
|
CStringW sw1;
|
CString s2;
|
//FilePathName=Prsfilepath+_T("\\")+savedfilename;
|
|
// ::SysLog(s1);
|
// wcscpy_s(wbuf1,1000,ToWChar(s1.GetBuffer(100)));
|
ULONG picquality = Quality;
|
Gdiplus::EncoderParameters paras1;
|
|
paras1.Count = 1;
|
paras1.Parameter[0].Guid = Gdiplus::EncoderQuality;
|
paras1.Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;
|
paras1.Parameter[0].NumberOfValues = 1;
|
paras1.Parameter[0].Value = &picquality;
|
|
IStream *ps2;
|
CreateStreamOnHGlobal(NULL, TRUE, &ps2);
|
bitmapsave.Save(ps2, &jpegClsid, ¶s1);
|
LARGE_INTEGER dlibMove;
|
dlibMove.QuadPart = 0;
|
ULARGE_INTEGER libNewPosition;
|
ps2->Seek(dlibMove, STREAM_SEEK_END, &libNewPosition);
|
int sizeImage;
|
sizeImage = libNewPosition.QuadPart;
|
ps2->Seek(dlibMove, STREAM_SEEK_SET, &libNewPosition);
|
void * pBuffer = new char[sizeImage];
|
DWORD dwRead;
|
ps2->Read(pBuffer, sizeImage, &dwRead);
|
*psizeImage = sizeImage;
|
*ppBuffer = pBuffer;
|
|
return 1;
|
|
}
|
|
HSI RGBToHSI(COLOR c1)
|
{
|
float nMax,nMin,ndelMax;
|
float ndelR,ndelG,ndelB;
|
float nH,nS,nV;
|
float nR,nB,nG;
|
HSI hsb2;
|
nR=c1.R/255.0f;
|
nG=c1.G/255.0f;
|
nB=c1.B/255.0f;
|
nMax=max(nR,max(nG,nB));
|
nMin=min(nR,min(nG,nB));
|
ndelMax=nMax-nMin;
|
nV=nMax;
|
if (ndelMax==0) {nS=0;nH=0;} //×î´óÖµÓë×îСֵÏàµÈ£¬´¿É«¡£
|
else
|
{
|
nS=ndelMax/nMax;
|
ndelR = (((nMax - nR) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
ndelG = (((nMax - nG) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
ndelB = (((nMax - nB) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
if (nR==nMax)
|
{
|
nH = ndelB - ndelG;
|
}
|
else if (nG==nMax)
|
{
|
nH = (1.0f / 3) + ndelR - ndelB;
|
|
}
|
else if (nB==nMax)
|
{
|
nH = (2.0f / 3) + ndelG - ndelR;
|
}
|
if (nH<0) {nH+=1;}
|
if (nH>1) {nH-=1;}
|
|
}
|
hsb2.H =(nH*240);
|
hsb2.S =(nS*240);
|
hsb2.I =(nV*240);
|
|
return hsb2 ;
|
}
|
/* RGB?-----------?Lab
|
(¸÷·ÖÁ¿ÊýÖµ·¶Î§£ºR/G/B: 0~255; L: 0~100, a/b:0~255)
|
|
RGB---?Lab:
|
X = 0.412453*R + 0.357580*G + 0.180423*B;
|
Y = 0.212671*R + 0.715160*G + 0.072169*B;
|
Z = 0.019334*R + 0.119193*G + 0.950227*B;
|
|
X = X/(255*0.950456);
|
Y = Y/255;
|
Z = Z/(255*1.088754);
|
Èç¹ûY > 0.008856£¬Ôò :
|
fY = Y^(1/3);
|
fX = X^(1/3);
|
fZ = Z^(1/3);
|
L= 116*fY - 16;
|
Èç¹ûY < 0.008856£¬Ôò
|
fY = 7.787*Y + 16/116;
|
fX = 7.787*X + 16/116;
|
fZ = 7.787*Z + 16/116;
|
L= 903.3*Y;
|
a = 500.0*(fX - fY) +128;
|
b = 200.0*(fY - fZ) +128;
|
|
Lab---?RGB:
|
a = a-128;
|
b = b-128;
|
fY = ((L + 16) / 116))^3;
|
Èç¹ûfY < 0.008856£¬ÔòfY = L / 903.3;
|
Y = fY;
|
Èç¹ûfY > 0.008856£¬ÔòfY = fY^(1/3);
|
Èç¹ûfY < 0.008856£¬ÔòfY = 7.787 * fY + 16/116;
|
|
fX = a / 500 + fY;
|
Èç¹ûfX > 0.206893£¬ÔòX = fX^(1/3);
|
Èç¹ûfX < 0.206893£¬ÔòX = (fX - 16/116) / 7.787;
|
|
fZ = fY - b /200;
|
Èç¹ûfZ > 0.206893£¬ÔòZ = fZ^(1/3);
|
Èç¹ûfX < 0.206893£¬ÔòZ = (fZ - 16/116) / 7.787;
|
|
X = X * 0.950456 * 255;
|
Y = Y *255;
|
Z = Z * 1.088754 * 255;
|
R = 3.240479*X - 1.537150*Y - 0.498535*Z
|
G =-0.969256*X + 1.875992*Y + 0.041556*Z;
|
B = 0.055648*X - 0.204043*Y + 1.057311*Z;
|
|
*/
|
|
/*
|
´ÓRGBµ½LabÉ«²Ê¿Õ¼äµÄת»»
|
2008ÄêÆßÔÂ27ÈÕ ÐÇÆÚÈÕ, 03:35 - ¼üÅÌÉúÑÄ / Programming
|
ËäÈ»Èô¸ÉÄêÇ°¾Í¿´¹ýÁ˹ØÓÚÉ«²Ê¿Õ¼äµÄ½éÉÜ£¬µ«ÊÇÖ±µ½½ñÌì²Å×Ô¼º¶¯ÊÖд´úÂë×öÕâ¼þÊÂÇé¡£ËäÈ»ÍøÂçÉÏÒѾÓкܶàÏֳɵÄÀý×Ó£¬µ«ÊÇÒ»Ôò½ö½öÊÊÓÃÓÚ¸¡µãÐ͵ÄÊý¾Ý£¬ÁíÒ»·½Ã棬ÔÚʵÏÖÉÏÒ²ÓÐһЩÉпÉÓÅ»¯Ö®´¦¡£
|
|
É«²ÊÄ£ÐͳýÁË×î³£¼ûµÄRGBÒÔÍ⣬»¹ÓÐHSB¡¢YCbCr¡¢XYZ¡¢LabµÈ¡£HSBÒ»°ã½ö½ö×÷ΪͼÏñ´¦Àí¹ý³ÌÖеÄÁÙʱģʽ£¬YCbCr³£³£ÓÃÓÚͼÏñµÄѹËõ´¦Àí£¬¶øXYZÔòÑϸñ°´ÕÕÈËÑÛ¶Ô¹âÐźŵÄÃô¸Ð¶È½øÐзֲ¼¡£
|
|
ÕâÀォҪÉÔ×÷ÌÖÂ۵ıãÊÇLabÄ£ÐÍ¡£ÍøÂçÉÏÖî¶àµÄ½éÉܶ¼ËµLabÊÇ»ùÓÚXYZµÄ£¬¹ÊÈËÃÇÒ»°ãÒ²Ö»ÄÜÕÒµ½XYZºÍLabÖ®¼äµÄת»»£¬¶øRGBµ½LabµÄת»»Ö»ÄÜʹÓÃXYZ×÷ΪÖмäģʽ¼ä½Ó½øÐС£¿ÉϧµÄÊÇ£¬ÕâÖÖÏÖ×´Ô´ÓÚÎó½â¡£¶øÔÚͼÏñ´¦ÀíÈí¼þÖУ¨±ÈÈçPhotoshop£©£¬ÍùÍù²ÉÓÃÒ»¸ö¸üΪ¼òµ¥µÄËã·¨¡£
|
|
ÎÒÃÇ¿ÉÒÔÏȹ۲ìRGBµ½XYZµÄת»»£º
|
[X,Y,Z] = [M] * [R,G,B]
|
|
ÆäÖÐMΪһ3x3¾ØÕó£º
|
[M] = [0.4125, 0.3576, 0.1805;
|
0.2126, 0.7152, 0.0722;
|
0.0193, 0.1192, 0.9505]£¬
|
|
RGBÊǾ¹ýGammaУÕýµÄÉ«²Ê·ÖÁ¿£ºR=g(r)£¬G=g(g)£¬B=g(b)¡£
|
ÆäÖÐrgbΪÔʼµÄÉ«²Ê·ÖÁ¿¡£
|
|
gÊÇGammaУÕýº¯Êý£º
|
µ± x < 0.018 ʱ£¬g(x) = 4.5318 * x
|
µ± x >= 0.018 ʱ£¬g(x) = 1.099 * d^0.45 - 0.099
|
|
rgbÒÔ¼°RGBµÄÈ¡Öµ·¶Î§Ôò¾ùΪ[0,1)¡£¼ÆËãÍê³Éºó£¬XYZµÄÈ¡Öµ·¶Î§ÔòÓÐËù±ä»¯£¬·Ö±ðÊÇ£º[0, 0.9506)£¬[0, 1)£¬[0, 1.0890)¡£
|
|
|
ÒÔ¼°XYZµ½LabµÄת»»£º
|
L = 116 * f(Y1) - 16
|
a = 500 * (f(X1) - f(Y1))
|
b = 200 * (f(Y1) - f(Z1))
|
|
ÆäÖÐfÊÇÒ»¸öÀàËÆGammaº¯ÊýµÄУÕýº¯Êý£º
|
µ± x > 0.008856 ʱ£¬f(x) = x^(1/3)
|
µ± x <= 0.008856 ʱ£¬f(x) = ( 7.787 * x ) + ( 16 / 116 )
|
X1¡¢Y1¡¢Z1·Ö±ðÊÇÏßÐÔ¹éÒ»»¯Ö®ºóµÄXYZÖµ£¬Ò²¾ÍÊÇ˵£¬ËüÃǵÄÈ¡Öµ·¶Î§¶¼ÊÇ[0, 1)¡£´ËÍ⣬º¯ÊýfµÄÖµÓòÒ²ºÍ×Ô±äÁ¿Ò»Ñù¶¼ÊÇ[0, 1)¡£
|
|
¼ÆËãÍê³Éºó£¬LµÄÈ¡Öµ·¶Î§[0, 100)£¬¶øaºÍbÔòԼΪ[-169, +169)ºÍ[-160, +160)¡£
|
|
|
ÔÚ¹Û²ìÕâЩòËƸ´Ôӵı任֮ǰ£¬ÎÒÃDZØÐëÈ·¶¨µÄÒ»¸ö¼ÙÉèÊÇ£ºÔÚͼÏñ´¦ÀíÈí¼þÖУ¬·ÇRGBÉ«²ÊÊý¾ÝµÄ¾ø¶ÔÖµ²¢²»ÖØÒª£¬ÖØÒªµÄÊÇËûÃÇÄܹ»¾¡¿ÉÄÜ׼ȷµÄ»¹Ô³ÉRGBͼÏñÒÔÏÔʾÔÚÆÁÄ»µÈÏà¹ØÉ豸ÉÏ¡£Õâ¸ö¼ÙÉèÊÇÎÒÃǵļò»¯µÃÒÔ³ÉÁ¢µÄÀíÓÉ¡£
|
|
ÉÏÃæµÄ´ÓXYZµ½LabµÄת»»Õ§Ò»¿´ÆðÀ´ºÜÆæ¹Ö£¬µ«ÈôÊÇ×Ðϸ¹Û²ì£¬²»ÄÑ·¢ÏÖLÓëY1Ö»ÊÇÒ»¸ö¼òµ¥µÄͬÇø¼äÓ³Éä¹Øϵ£¬Õâ¸öÓ³ÉäÆäʵ¿ÉÓпÉÎÞ£¨Èç¹û½øÐÐÁËÓ³Éä·´¶ø±Ø¶¨µ¼ÖÂÉ«½×¶ªÊ§£©¡£
|
|
ÕâÑù£¬ÎÒÃÇÈ¡µÃµÄµÚÒ»¸ö¼ò»¯ÊÇ£ºL = Y1¡£
|
|
½ÓÏÂÀ´½Ó×Å¿´aºÍbµÄÓ³Éä¹ý³Ì¡£´ó¼Ò²»ÄÑ·¢ÏÖ£¬aºÍbÆäʵÊÇÒ»¸öÉ«²îÐźţ¨¸úCbºÍCrµÄÐÔÖʲ¶à£©¡£ÖÁÓÚËüÃǵÄת»»ÏµÊý500ºÍ200£¬´ó¼Ò¿ÉÒÔÍêÈ«Íü¼Ç£¬ÒòΪËûÃǵÄÖµÓò²¢²»·ûºÏ8λÕûÊýÖµµÄ±í´ïÐèÒª¡£ÎÒÃǽ«»áÉÔºó¼ÆËã³öºÏÊʵÄÒòÊý£¬Ê¹µÃaºÍb¶¼´¦ÔÚ[0, 255]µÄ·¶Î§ÄÚ¡£
|
|
ÒòΪXYZ±ØÐë¹éÒ»»¯×ªÎªX1Y1Z1£¬ÄÇôÎÒÃÇÆäʵ¿ÉÒÔÔÚת»»¾ØÕóMÖÐ×÷³öÕâ¸öÐ޸ģ¬ÁîÿÐгËÒÔÒ»¸öϵÊýÒÔʹµÃÿÐи÷ÊýÖ®ºÍΪ1£º
|
[M1] = [0.4339, 0.3762 0.1899;
|
0.2126, 0.7152, 0.0722;
|
0.0177, 0.1095, 0.8728]
|
|
ÓÚÊǺõ£¬ÎÒÃǵóöÒ»¸ö°ë³ÉÆ·£º
|
L = Y1 = 0.2126 * R + 0.7152 * G + 0.0722 * B
|
a = Fa * (X1 - Y1) + Da
|
b = Fb * (Y1 - Z1) + Db
|
ÆäÖеÄFxÊǵ÷ÕûÖµÓòÓõÄϵÊý£¬DxÊÇÒ»¸öÕýÊý£¬ÓÃÀ´Ïû³ýaºÍbµÄ¸ºÖµ¡£FxºÍDxµÄÑ¡È¡±ØÐëÁîaºÍbÂú×ãÖµÓòÔÚ[0, 255]Éϵķֲ¼¡£
|
|
½ÓÏÂÀ´ÎÒÃÇÀ´È·¶¨FxºÍDxµÄÖµ¡£Í¨¹ýM1ÎÒÃǺÜÈÝÒ×¼ÆËã³öX1-Y1µÄÖµÓò£¨¼«¶ËÇé¿ö£©Îª[-86.784, +86.784)£¬¶øY1-Z1µÄÖµÓòÔòΪ[-204.9536, +204.9536)¡£ÓÚÊǺõ£¬FaµÄֵΪ1.4749£¬FbµÄֵΪ0.6245£»DaºÍDbÔò¶¼ÊÇ128¡£
|
|
Õâʱ£¬´úÈëM1ÓУº
|
L = Y1 = 0.2126 * R + 0.7152 * G + 0.0722 * B
|
a = 1.4749 * (0.2213 * R - 0.3390 * G + 0.1177 * B) + 128
|
b = 0.6245 * (0.1949 * R + 0.6057 * G - 0.8006 * B) + 128
|
ÆäÖÐRGBºÍLabµÄÈ¡Öµ·¶Î§¶¼ÊÇ[0,255]¡£
|
|
×îºóµÄÒ»µã¹¤×÷ÊÇËã·¨µÄÓÅ»¯¡£ÎÒÃÇ¿ÉÒÔ½«Õâ¸ö·½³Ì×éת»»³É³£ÕûÊý³Ë·¨ÓëÒÆλµÄ·½Ê½£¨Ï൱ÓÚʹÓö¨µãÊý£©¡£ÎªÁË·½±ãÔĶÁ£¬ÎÒÈÔÈ»½«ÒÆλдΪ³ý·¨¡£
|
|
ËùÒÔÎÒÃǵÄ×îÖÕ½á¹ûΪ£º
|
L = Y1 = (13933 * R + 46871 * G + 4732 * B) div 2^16
|
a = 377 * (14503 * R - 22218 * G + 7714 * B) div 2^24 + 128
|
b = 160 * (12773 * R + 39695 * G - 52468 * B) div 2^24 + 128
|
|
|
ÖÁÓÚÄæ±ä»»Ôò¿ÉÒÔÓÃÀàËƵķ½·¨ÍƵ¼³öÀ´£º
|
ÉèL1=L£¬a1=(a-128)*174£¬b1=(b-128)*410£¬ÓУº
|
R = L1 + (a1 * 100922 + b1 * 17790) div 2^23
|
G = L1 - (a1 * 30176 + b1 * 1481) div 2^23
|
B = L1 + (a1 * 1740 - b1 * 37719) div 2^23
|
ÆäÖÐRGBºÍLabµÄÈ¡Öµ·¶Î§¶¼ÊÇ[0,255]£¬ÔÙ¾¹ýÄæGammaº¯ÊýÈ¡µÃÔʼµÄrgb
|
|
|
ÒÔÉϵÄËã·¨ÔÚDelphiÖбàÒëͨ¹ý¡£¾²âÊÔ£¬ÔËËãµÃ³öµÄÖ±·½Í¼ÓëͼƬ¹Û¸ÐºÍÎÒÊÖÍ·µÄPhotoshop CSµÄ½á¹û·Ç³£ÏàËÆ£¬µ«Ò²ÓÐһЩ·ù¶ÈÉϵIJî±ð£¬ÇÒÈÝÒÔºóÂýÂýϸ²ì¡£
|
|
µ±³õΪÁËÑ°ÃÙÒ»¸ö¼òµ¥µÄRGBÖ±½ÓתLabËã·¨¶øÕÒ±éÍøÂç½Ô²»µÃ£¬Íò²»µÃÒÑÖ»ºÃ×ÔÁ¦¸üÉú¡£Æä¼äËä·ÑʱһÈÕ£¬ÐÒºÃÒ²ËãÂÔÓÐËùµÃ¡£ÔݼÇÓÚ´Ë£¬ÒÔÀûºóÈË¡£Æä¼ä»òÐíÄÑÃâ´í©֮´¦£¬»¹Íû´ïÈ˲»ÁßÖ¸µã¡£
|
|
|
|
*/
|
Lab RGBfToLab(COLORf &c1f)
|
{
|
float X,Y,Z,fX,fY,fZ;
|
Lab lab1;
|
float R,G,B;
|
R=c1f.R;
|
G=c1f.G;
|
B=c1f.B;
|
// if (!(R>=0)||!(R<=256))
|
// {
|
// lab1.L=0;lab1.a=0;lab1.b=0;
|
// return lab1;
|
// }
|
|
X = (0.0017017755110158063242130877282104f*R + 0.0014753702536507966372219765884924f*G + 0.00074442286278437743072179842839524f*B);
|
Y = (0.00083400392156862745098039215686275f*R + 0.0028045490196078431372549019607843f*G + 0.00028301568627450980392156862745098f*B);
|
Z = (0.000069638878794601218367014756605923f*R + 0.00042931968967440276305056325044635f*G + 0.0034226100589819764107392847380458f*B);
|
|
if (Y > 0.008856451679f) // ½øÐÐÐÞÕý, (6/29)^3 ,Ô¼ 1/113;
|
{
|
fY = pow(Y,(1.0f/3));
|
lab1.L= 116*fY - 16;
|
}
|
else
|
{
|
fY = 7.787f*Y + 16.0f/116;
|
lab1.L= 903.3f*Y;
|
}
|
if (X > 0.008856451679f) // ½øÐÐÐÞÕý, (6/29)^3 ,Ô¼ 1/113;
|
fX = pow(X,(1.0f/3));
|
else fX = 7.787f*X + 16.0f/116;
|
|
if (Z > 0.008856451679f) // ½øÐÐÐÞÕý, (6/29)^3 ,Ô¼ 1/113;
|
fZ = pow(Z,(1.0f/3));
|
else fZ = 7.787f*Z + 16.0f/116;
|
|
lab1.a = 500.0f*(fX - fY) +128;
|
lab1.b = 200.0f*(fY - fZ) +128;
|
return lab1;
|
|
}
|
COLORf LabToRGBf(Lab lab1)
|
{
|
float X,Y,Z,fX,fY,fZ;
|
COLORf c1f;
|
float L,a,b;
|
a = lab1.a-128;
|
b = lab1.b-128;
|
L=lab1.L;
|
fY = pow(((L + 16) / 116.0f),3.0f);
|
if (fY <= 0.008856f) {fY = L / 903.3f;}
|
Y = fY;
|
if (Y > 0.008856f) {fY = pow(Y,(1.0f/3));}
|
if (Y <= 0.008856f) {fY = 7.787f * Y + 16.0f/116;}
|
|
fX = a / 500 + fY;
|
if (fX > 0.206893f) {X = pow(fX,(3.0f));}
|
if (fX <= 0.206893f) {X = (fX - 16.0f/116) / 7.787f;}
|
|
fZ = fY - b /200;
|
if (fZ > 0.206893f) {Z = pow(fZ,(3.0f));}
|
if (fZ <= 0.206893f) {Z = (fZ - 16.0f/116) / 7.787f;}
|
|
X = X * 0.950456f * 255;
|
Y = Y *255;
|
Z = Z * 1.088754f * 255;
|
|
c1f.R = 3.240479f*X - 1.537150f*Y - 0.498535f*Z;
|
c1f.G =-0.969256f*X + 1.875992f*Y + 0.041556f*Z;
|
c1f.B = 0.055648f*X - 0.204043f*Y + 1.057311f*Z;
|
return c1f;
|
}
|
HSI RGBfToHSI(COLORf &c1)
|
{
|
float nMax,nMin,ndelMax;
|
float ndelR,ndelG,ndelB;
|
float nH,nS,nV;
|
float nR,nB,nG;
|
HSI hsb2;
|
nR=c1.R/255.0f;
|
nG=c1.G/255.0f;
|
nB=c1.B/255.0f;
|
if (!(nR>=0)||!(nR<=256))
|
{
|
hsb2.H=0;hsb2.S=0;hsb2.I=0;
|
return hsb2;
|
}
|
nMax=max(nR,max(nG,nB));
|
nMin=min(nR,min(nG,nB));
|
ndelMax=nMax-nMin;
|
nV=nMax;
|
|
if (ndelMax==0) {nS=0;nH=0;} //×î´óÖµÓë×îСֵÏàµÈ£¬´¿É«¡£
|
else
|
{
|
nS=ndelMax/nMax;
|
ndelR = (((nMax - nR) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
ndelG = (((nMax - nG) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
ndelB = (((nMax - nB) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
if (nR==nMax)
|
{
|
nH = ndelB - ndelG;
|
}
|
else if (nG==nMax)
|
{
|
nH = (1.0f / 3) + ndelR - ndelB;
|
|
}
|
else if (nB==nMax)
|
{
|
nH = (2.0f / 3) + ndelG - ndelR;
|
}
|
if (nH<0) {nH+=1;}
|
if (nH>1) {nH-=1;}
|
|
}
|
hsb2.H =(nH*240);
|
hsb2.S =(nS*240);
|
hsb2.I =(nV*240);
|
|
return hsb2 ;
|
}
|
|
DWORD HSIToRGB(HSI hsb1)
|
{
|
COLOR color2;
|
float nH,nS,nV;
|
float nR,nG,nB;
|
float f,p,q,t;
|
int k;
|
nH=hsb1.H/240.0f;
|
nS=hsb1.S/240.0f;
|
nV=hsb1.I/240.0f;
|
k = (int)( (int(hsb1.H) / 40) % 6);
|
f = (hsb1.H / 40.0f) - k;
|
p=nV*(1-nS);
|
q=nV*(1-f*nS);
|
t=nV*(1-(1-f)*nS);
|
if (k==0)
|
{
|
nR=nV;nG=t;nB=p;
|
} else if (k==1)
|
{ nR=q;nG=nV;nB=p;
|
} else if (k==2)
|
{ nR=p;nG=nV;nB=t;
|
} else if (k==3)
|
{ nR=p;nG=q;nB=nV;
|
} else if (k==4)
|
{ nR=t;nG=p;nB=nV;}
|
else if (k==5)
|
{ nR=nV;nG=p;nB=q;}
|
color2.R=int(nR*255);color2.G=int(nG*255);color2.B=int(nB*255);
|
//R=nV*100;G=nV*100;B=nV*100;
|
|
return color2.argb ;
|
}
|
|
COLORf HSIToRGBf(HSI hsb1)
|
{
|
COLORf color2;
|
float nH,nS,nV;
|
float nR,nG,nB;
|
float f,p,q,t;
|
int k;
|
nH=hsb1.H/240.0f;
|
nS=hsb1.S/240.0f;
|
nV=hsb1.I/240.0f;
|
k = (int)( (int(hsb1.H) / 40) % 6);
|
f = (hsb1.H / 40.0f) - k;
|
p=nV*(1-nS);
|
q=nV*(1-f*nS);
|
t=nV*(1-(1-f)*nS);
|
if (k==0)
|
{
|
nR=nV;nG=t;nB=p;
|
} else if (k==1)
|
{ nR=q;nG=nV;nB=p;
|
} else if (k==2)
|
{ nR=p;nG=nV;nB=t;
|
} else if (k==3)
|
{ nR=p;nG=q;nB=nV;
|
} else if (k==4)
|
{ nR=t;nG=p;nB=nV;}
|
else if (k==5)
|
{ nR=nV;nG=p;nB=q;}
|
color2.R=nR*255;color2.G=nG*255;color2.B=nB*255;
|
//R=nV*100;G=nV*100;B=nV*100;
|
|
return color2 ;
|
}
|
|
#define EVEN(x) ((srcbuf[(x)*3/2]<<4)+(srcbuf[(x)*3/2+1]&0xf))
|
#define ODD(x) (((*(unsigned short *)(&srcbuf[(x)*3/2+1]))>>4)&0x0fff)
|
int Raw12toRaw16(void * dest,void * src,int width,int height)
|
{
|
int i,l;//,k,l;
|
unsigned short int a,b;
|
unsigned short int * destbuf=(unsigned short *)dest;
|
unsigned char * srcbuf=(unsigned char *)src;
|
l=width*height;
|
// memcpy(destbuf,srcbuf,l);
|
// memcpy(destbuf+width*height/2,srcbuf,l);
|
// return 0;
|
for (i=0;i<l;i+=2)
|
{
|
// a=(srcbuf[i*3/2]<<8)+((srcbuf[i*3/2+1]&0x0f)<<4);
|
// b=(srcbuf[i*3/2+2]<<8)+(srcbuf[i*3/2+1]&0xf0);
|
a=EVEN(i)*16;
|
b=ODD(i)*16;
|
destbuf[i]=a;
|
destbuf[i+1]=b;
|
}
|
return 0;
|
}
|
|
int Raw12ToRaw8(void * dest, void * src, int width, int height)
|
{
|
int i,l; //j,k,
|
// unsigned short int a,b;
|
unsigned char * destbuf=(unsigned char *)dest;
|
unsigned char * srcbuf=(unsigned char *)src;
|
l=width*height;
|
// memcpy(destbuf,srcbuf,l);
|
// memcpy(destbuf+width*height/2,srcbuf,l);
|
// return 0;
|
for (i=0;i<l;i+=2)
|
{
|
// a=(srcbuf[i*3/2]<<8)+((srcbuf[i*3/2+1]&0x0f)<<4);
|
// b=(srcbuf[i*3/2+2]<<8)+(srcbuf[i*3/2+1]&0xf0);
|
//a=EVEN(i)*16;
|
//b=ODD(i)*16;
|
destbuf[i]=srcbuf[i*3/2];
|
destbuf[i+1]=srcbuf[i*3/2+2];
|
}
|
return 0;
|
}
|
|
int BayerGB12PackedToRGB32(void * dest,void * src,int width,int height,float gamma)
|
{
|
int i,j,k,l,m,n,p;
|
// unsigned short int a,b;
|
COLOR * destbuf=(COLOR *)dest;
|
unsigned char * srcbuf=(unsigned char *)src;
|
// return 0;
|
unsigned char LUTgamma[4096];
|
for (i=0;i<4096;i++)
|
{
|
j=int(pow(i/4096.0f,gamma)*256+0.5);
|
if (j>255) {j=255;}
|
LUTgamma[i]=j;
|
|
}
|
unsigned short int buf1[4][3200];
|
unsigned short int G00,B01,G02,B03;
|
unsigned short int R10,G11,R12,G13;
|
unsigned short int G20,B21,G22,B23;
|
unsigned short int R30,G31,R32,G33;
|
|
for (i=0;i<3;i++)
|
{
|
l=i*width;
|
for (j=0;j<width;j+=2)
|
{
|
buf1[i][j]=EVEN(l+j);buf1[i][j+1]=ODD(l+j);
|
}
|
}
|
|
for (i=0;i<height-2;i+=2)
|
{
|
l=i*width;
|
m=l+width;
|
n=m+width;
|
p=n+width;
|
for (j=0;j<width;j+=4)
|
{
|
k=*(unsigned *)(srcbuf+(n+j)*3/2);
|
*((unsigned *)&buf1[(i+2)&0x3][j])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
|
k=*(unsigned *)(srcbuf+(n+j+2)*3/2);
|
*((unsigned *)&buf1[(i+2)&0x3][j+2])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
|
// buf1[(i+2)&0x3][j]=EVEN(n+j);buf1[(i+2)&0x3][j+1]=ODD(n+j);
|
// buf1[(i+2)&0x3][j+2]=EVEN(n+j+2);buf1[(i+2)&0x3][j+3]=ODD(n+j+2);
|
|
}
|
for (j=0;j<width;j+=4)
|
{
|
k=*(unsigned *)(srcbuf+(p+j)*3/2);
|
*((unsigned *)&buf1[(i+3)&0x3][j])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
|
k=*(unsigned *)(srcbuf+(p+j+2)*3/2);
|
*((unsigned *)&buf1[(i+3)&0x3][j+2])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
|
// buf1[(i+3)&0x3][j]=EVEN(p+j);buf1[(i+3)&0x3][j+1]=ODD(p+j);
|
// buf1[(i+3)&0x3][j+2]=EVEN(p+j+2);buf1[(i+3)&0x3][j+3]=ODD(p+j+2);
|
|
}
|
|
for (j=0;j<width-2;j+=2)
|
{
|
// G00=EVEN(l+j);B01=ODD(l+j);G02=EVEN(l+j+2);B03=ODD(l+j+2);
|
// R10=EVEN(m+j);G11=ODD(m+j);R12=EVEN(m+j+2);G13=ODD(m+j+2);
|
// G20=EVEN(n+j);B21=ODD(n+j);G22=EVEN(n+j+2);B23=ODD(n+j+2);
|
// R30=EVEN(p+j);G31=ODD(p+j);R32=EVEN(p+j+2);G33=ODD(p+j+2);
|
G00=buf1[(i+0)&3][j];B01=buf1[(i+0)&3][j+1];G02=buf1[(i+0)&3][j+2];B03=buf1[(i+0)&3][j+3];
|
R10=buf1[(i+1)&3][j];G11=buf1[(i+1)&3][j+1];R12=buf1[(i+1)&3][j+2];G13=buf1[(i+1)&3][j+3];
|
G20=buf1[(i+2)&3][j];B21=buf1[(i+2)&3][j+1];G22=buf1[(i+2)&3][j+2];B23=buf1[(i+2)&3][j+3];
|
R30=buf1[(i+3)&3][j];G31=buf1[(i+3)&3][j+1];R32=buf1[(i+3)&3][j+2];G33=buf1[(i+3)&3][j+3];
|
/*
|
destbuf[l+j].B=LUTgamma[B01];destbuf[l+j].G=LUTgamma[(G00+G11)/2];destbuf[l+j].R=LUTgamma[R10];
|
destbuf[l+j+1].B=LUTgamma[B01];destbuf[l+j+1].G=LUTgamma[(G11+G02)/2];destbuf[l+j+1].R=LUTgamma[R12];
|
|
destbuf[m+j].B=LUTgamma[B21];destbuf[m+j].G=LUTgamma[(G20+G11)/2];destbuf[m+j].R=LUTgamma[R10];
|
destbuf[m+j+1].B=LUTgamma[B21];destbuf[m+j+1].G=LUTgamma[(G11+G22)/2];destbuf[m+j+1].R=LUTgamma[R12];
|
*/
|
|
destbuf[m+j+1].B=LUTgamma[(B01+B21)/2];
|
destbuf[m+j+1].G=LUTgamma[G11];
|
destbuf[m+j+1].R=LUTgamma[(R10+R12)/2];
|
|
destbuf[m+j+2].B=LUTgamma[(B01+B21+B03+B23)/4];
|
if (abs(G02-G22)<abs(G11-G13)) {destbuf[m+j+2].G=LUTgamma[(G02+G22)/2];}
|
else if (abs(G02-G22)>abs(G11-G13)) {destbuf[m+j+2].G=LUTgamma[(G11+G13)/2];}
|
else {destbuf[m+j+2].G=LUTgamma[(G02+G22+G11+G13)/4];}
|
destbuf[m+j+2].R=LUTgamma[R12];
|
|
destbuf[n+j+1].B=LUTgamma[B21];
|
if (abs(G11-G31)<abs(G20-G22)) {destbuf[n+j+1].G=LUTgamma[(G11+G31)/2];}
|
else if (abs(G11-G31)>abs(G20-G22)) {destbuf[n+j+1].G=LUTgamma[(G20+G22)/2];}
|
else {destbuf[n+j+1].G=LUTgamma[(G11+G31+G20+G22)/4];}
|
destbuf[n+j+1].R=LUTgamma[(R10+R30+R12+R32)/4];
|
|
destbuf[n+j+2].B=LUTgamma[(B21+B23)/2];
|
destbuf[n+j+2].G=LUTgamma[G22];
|
destbuf[n+j+2].R=LUTgamma[(R12+R32)/2];
|
|
|
}
|
}
|
return 0;
|
}
|
|
/*
|
|
|
R03=srcbuf[k+2];
|
B12=srcbuf[l+1];G13=srcbuf[l+2];
|
G22=srcbuf[m+1];R23=srcbuf[m+2];
|
B32=srcbuf[n+1];
|
|
|
for (j=2;j<width-6;j+=2)
|
{
|
// ÆæÊýÐÐ
|
R01=R03; G02=srcbuf[k+j+1]; R03=srcbuf[k+j+2];
|
B10=B12; G11=G13; B12=srcbuf[l+j+1]; G13=srcbuf[l+j+2];
|
G20=G22; R21=R23; G22=srcbuf[m+j+1]; R23=srcbuf[m+j+2];
|
B30=B32; G31=srcbuf[n+j]; B32=srcbuf[n+j+1];
|
|
*/
|
|
int BayerGB16toRGB64(void * dest,void * src,int width,int height)
|
{
|
int i,j,k,l,m,n,p,q,s;
|
//unsigned short R,G,B,R1,R2,R3,R4,G1,G2,G3,G4,B1,B2,B3,B4;
|
unsigned short G00, B01, G02, B03, G04, B05;
|
unsigned short R10, G11, R12, G13, R14, G15;
|
unsigned short G20, B21, G22, B23, G24, B25;
|
unsigned short R30, G31, R32, G33, R34, G35;
|
unsigned short G40, B41, G42, B43, G44, B45;
|
unsigned short R50, G51, R52, G53, R54, G55;
|
|
unsigned long long * destbuf=(unsigned long long *) dest;
|
unsigned short * srcbuf=(unsigned short *)src;
|
s=width;
|
G00=0;
|
RGB16 pixel;
|
|
for (i=2;i<height-4;i+=2)
|
{
|
k=i*width-width-width; //ÉÏÒ»ÐÐ
|
l=i*width-width; //µ±Ç°ÐÐ
|
m=i*width; //ÏÂÒ»ÐÐ
|
n=m+width; //ÏÂÁ½ÐÐ
|
p=m+width+width;
|
q=m+width+width+width;
|
B01=srcbuf[k+1];G02=srcbuf[k+2];B03=srcbuf[k+3];G04=srcbuf[k+4];B05=srcbuf[k+5];
|
R10=srcbuf[l+0];G11=srcbuf[l+1];R12=srcbuf[l+2];G13=srcbuf[l+3];R14=srcbuf[l+4];G15=srcbuf[l+5];
|
G20=srcbuf[m+0];B21=srcbuf[m+1];G22=srcbuf[m+2];B23=srcbuf[m+3];G24=srcbuf[m+4];B25=srcbuf[m+5];
|
R30=srcbuf[n+0];G31=srcbuf[n+1];R32=srcbuf[n+2];G33=srcbuf[n+3];R34=srcbuf[n+4];G35=srcbuf[n+5];
|
G40=srcbuf[p+0];B41=srcbuf[p+1];G42=srcbuf[p+2];B43=srcbuf[p+3];G44=srcbuf[p+4];B45=srcbuf[p+5];
|
R50=srcbuf[q+0];G51=srcbuf[q+1];R52=srcbuf[q+2];G53=srcbuf[q+3];R54=srcbuf[q+4];G55=srcbuf[q+5];
|
|
for (j=2;j<width-6;j+=2)
|
{
|
// ÆæÊýÐÐ
|
|
B01=srcbuf[k+j+1];G02=srcbuf[k+j+2];B03=srcbuf[k+j+3];G04=srcbuf[k+j+4];B05=srcbuf[k+j+5];
|
R10=srcbuf[l+j+0];G11=srcbuf[l+j+1];R12=srcbuf[l+j+2];G13=srcbuf[l+j+3];R14=srcbuf[l+j+4];G15=srcbuf[l+j+5];
|
G20=srcbuf[m+j+0];B21=srcbuf[m+j+1];G22=srcbuf[m+j+2];B23=srcbuf[m+j+3];G24=srcbuf[m+j+4];B25=srcbuf[m+j+5];
|
R30=srcbuf[n+j+0];G31=srcbuf[n+j+1];R32=srcbuf[n+j+2];G33=srcbuf[n+j+3];R34=srcbuf[n+j+4];G35=srcbuf[n+j+5];
|
G40=srcbuf[p+j+0];B41=srcbuf[p+j+1];G42=srcbuf[p+j+2];B43=srcbuf[p+j+3];G44=srcbuf[p+j+4];B45=srcbuf[p+j+5];
|
R50=srcbuf[q+j+0];G51=srcbuf[q+j+1];R52=srcbuf[q+j+2];G53=srcbuf[q+j+3];R54=srcbuf[q+j+4];G35=srcbuf[q+j+5];
|
|
pixel.B=(B21+B23)/2;
|
pixel.G=G22;
|
pixel.R=(R12+R32)/2;
|
((RGB16 *)(&destbuf[m+j]))->ARGB=pixel.ARGB ;
|
|
pixel.B=B23;
|
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
//else{pixel.G=(G22+G24)/2;}
|
if (abs(signed(B03+B43-B23*2))<abs(signed(B21+B25-B23*2))) {pixel.G=(G13+G33)/2;}
|
else {pixel.G=(G22+G24)/2;}
|
|
pixel.R=((unsigned int )R12+R32+R14+R34)/4;
|
destbuf[m+j+1]=pixel.ARGB ;
|
|
//żÊýÐÐ
|
pixel.B=((unsigned int )B21+B41+B23+B43)/4;
|
if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
else{pixel.G=(G31+G33)/2;}
|
|
pixel.R=R32;
|
destbuf[n+j]=pixel.ARGB ;
|
|
pixel.B=(B23+B43)/2;
|
pixel.G=G33;
|
pixel.R=(R32+R34)/2;
|
destbuf[n+j+1]=pixel.ARGB ;
|
}
|
}
|
return 0;
|
}
|
int RGB64toRGB32(void * destbuf,void * srcbuf,int width,int height)
|
{
|
int i,j,l,s;
|
s=width;
|
l=width*height;
|
RGB16 * pixel=(RGB16 *)srcbuf;
|
COLOR * c1=(COLOR *) destbuf;
|
for (i=0;i<height;i++)
|
{
|
l=s*i;
|
for (j=0;j<width;j++)
|
{
|
c1[l+j].R=pixel[l+j].R>>8;
|
c1[l+j].G=pixel[l+j].G>>8;
|
c1[l+j].B=pixel[l+j].B>>8;
|
c1[l+j].A=pixel[l+j].A>>8;
|
}
|
}
|
return 0;
|
}
|
|
int RGB32toRGB64(void * destbuf,void * srcbuf,int width,int height)
|
{
|
int i,l;
|
l=width*height;
|
RGB16 * pixel=(RGB16 *)destbuf;
|
COLOR * c1=(COLOR *)srcbuf;
|
for (i=0;i<l;i++)
|
{
|
pixel[i].R=c1[i].R<<8;
|
pixel[i].G=c1[i].G<<8;
|
pixel[i].B=c1[i].B<<8;
|
pixel[i].A=c1[i].A<<8;
|
}
|
return 0;
|
}
|
/*
|
float CalHSIDistance(HSI hsb1, HSI hsb2)
|
{
|
float nH1,nH2,nS1,nS2,nV1,nV2;
|
float delH,delS,delV;
|
float kH,kS,kV;
|
CString s1;
|
float PercentH,PercentS,PercentV;
|
PercentH=1.0f;PercentS=0.10f;PercentV=0.05f;
|
kH=PercentH;//1.0f
|
kS=PercentS;//0.4f;
|
kV=PercentV;//0.1f;
|
nH1=hsb1.H/240.0f;nH2=hsb2.H/240.0f;
|
nS1=hsb1.S/240.0f;nS2=hsb2.S/240.0f;
|
nV1=hsb1.I/240.0f;nV2=hsb2.I/240.0f;
|
delH=nH1-nH2;
|
delS=nS1-nS2;
|
delV=nV1-nV2;
|
float distance;
|
if (delH<0) {delH+=1;}
|
if (delH>0.5) {delH=1-delH;}
|
|
distance=sqrtf(kH*kH*delH*delH+kS*kS*delS*delS+kV*kV*delV*delV)*240.0f;
|
// s1.Format(_T("%d %d %d %d %d %d %.3f %.3f %.3f %.3f\r\n"),hsb1.H,hsb1.S,hsb1.I,hsb2.H,hsb2.S,hsb2.I,delH,delS,delV,distance);
|
// SysLog(s1);
|
return distance;
|
return 0;
|
}
|
*/
|
/*
|
float Calk(HSI hsb0,HSI hsb1,HSI hsb2)
|
{
|
float k; //¼ÆËã¿Õ¼äµã¶ÔÖ±ÏߵĴ¹×ãλÖ㬼´´¹×ãÔÚÖ±ÏßÉϵÄÁ½µãÖ®¼äµÄ±ÈÀý¡£
|
//hsb0Ϊ¿Õ¼äµã£¬hsb1ºÍhsb2È·¶¨¿Õ¼äÖ±Ïß¡£
|
float x0,x1,x2,y0,y1,y2,z0,z1,z2;
|
float PercentH,PercentS,PercentV;
|
PercentH=1.0f;PercentS=0.10f;PercentV=0.05f;
|
x0=hsb0.H*PercentH;
|
x1=hsb1.H*PercentH;
|
x2=hsb2.H*PercentH;
|
y0=hsb0.S*PercentS;
|
y1=hsb1.S*PercentS;
|
y2=hsb2.S*PercentS;
|
z0=hsb0.I*PercentV;
|
z1=hsb1.I*PercentV;
|
z2=hsb2.I*PercentV;
|
k=((x0-x1)*(x2-x1)+(y0-y1)*(y2-y1)+(z0-z1)*(z2-z1)) / ((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1));
|
return k;
|
}
|
*/
|
/*
|
float CalPos(HSI hsb1)
|
{
|
float n;
|
int i;
|
int lastCheckedClass=0;
|
float kPosition[maxClasses];
|
HSI chsb1,chsb2;
|
HSI hsbs[100];
|
float Nf[100];
|
float distancehsb[100];
|
int TotalHsbs;
|
float k;
|
//ÏȽ«ËùÓÐÑÕÉ«µãͳ¼Æ³öÀ´£»»¹Óи÷ÑÕÉ«µã¶ÔÓ¦µÄ·ÖÖµ£»
|
TotalHsbs=0;
|
for (i=0;i<TotalClasses;i++)
|
{
|
if (Classes[i].isChecked)
|
{
|
hsbs[0]=Classes[i].hsb1;
|
Nf[0]=Classes[i].N1;
|
TotalHsbs++;
|
break;
|
}
|
}
|
for (i=0;i<TotalClasses;i++)
|
{
|
if (Classes[i].isChecked)
|
{
|
hsbs[TotalHsbs]=Classes[i].hsb2;
|
Nf[TotalHsbs]=Classes[i].N2;
|
TotalHsbs++;
|
}
|
}
|
//È»ºóÕÒµ½¾àÀë×î½üµÄÑÕÉ«µã£»
|
|
for (i=0;i<TotalHsbs;i++)
|
{
|
distancehsb[i]=CalHSIDistance(hsb1,hsbs[i]);
|
}
|
float mindistance;
|
int mindistanceindex;
|
mindistance=99999;
|
mindistanceindex=0;
|
for (i=0;i<TotalHsbs;i++)
|
{
|
if (distancehsb[i]<mindistance)
|
{
|
mindistance=distancehsb[i];
|
mindistanceindex=i;
|
}
|
}
|
//ÕÒµ½¾àÀë×î½üµÄµã£¬indexΪi;
|
//¿´¿´×î½ü¾àÀëµÄµãÊÇ·ñΪ±ßÔµµã¡£
|
if (mindistance>=2.0f)
|
{
|
n=-1;
|
return n;
|
}
|
if (mindistanceindex==0)
|
{ //±ßÔµµã£¬Ò²·ÖÂäÔÚ±ßÔµÄںͱßÔµÍâ
|
k=Calk(hsb1,hsbs[0],hsbs[1]);
|
if (k<0) //ÂäÔÚ±ßÔµµãÍâ
|
{
|
n=(Nf[1]-Nf[0])*k+Nf[0];
|
return n;
|
}
|
else
|
{ //ÂäÔÚ±ßÔµµãÄÚ
|
n=(Nf[1]-Nf[0])*k+Nf[0];
|
return n;
|
}
|
}
|
else if (mindistanceindex==TotalHsbs-1)
|
{ //±ßÔµµã£¬Ò²·ÖÂäÔÚ±ßÔµÍâºÍ±ßÔµÄÚ
|
k=Calk(hsb1,hsbs[mindistanceindex-1],hsbs[mindistanceindex]);
|
if (k>1) //ÂäÔÚ±ßÔµµãÍâ
|
{
|
n=(Nf[i]-Nf[mindistanceindex-1])*k+Nf[mindistanceindex-1];
|
return n;
|
}
|
else
|
{ //ÂäÔÚ±ßÔµµãÄÚ
|
n=(Nf[mindistanceindex]-Nf[mindistanceindex-1])*k+Nf[mindistanceindex-1];
|
return n;
|
}
|
}
|
else
|
{ //Öмäµã
|
//Òª¿´¿¿ÖмäµãµÄÄĶË
|
float k1,k2;
|
float n1,n2;
|
k1=Calk(hsb1,hsbs[mindistanceindex-1],hsbs[mindistanceindex]);
|
k2=Calk(hsb1,hsbs[mindistanceindex],hsbs[mindistanceindex+1]);
|
n1=(Nf[mindistanceindex]-Nf[mindistanceindex-1])*k1+Nf[mindistanceindex-1];
|
n2=(Nf[mindistanceindex+1]-Nf[mindistanceindex])*k2+Nf[mindistanceindex];
|
if (k1<=1&&k2<0) //´¦ÓÚÒ»²àµã¡£
|
{
|
n=n1;
|
return n;
|
}
|
if (k1>1&&k2<0) //´¦ÓÚÁ½µãÖ®¼ä£¬ÍâÍä
|
{
|
n=Nf[i];
|
return n;
|
}
|
if (k1<=1&&k2>=0) //´¦ÓÚÁ½µãÖ®¼ä£¬ÄÚÍä
|
{
|
n=(n1+n2)/2;
|
return n;
|
}
|
if (k1>=1&&k2>=0) //´¦ÓÚÁíÒ»²àµã
|
{
|
n=n2;
|
return n;
|
}
|
|
}
|
for (i=0;i<TotalClasses;i++)
|
{
|
if (!Classes[i].isChecked) {continue;}
|
chsb1=Classes[i].hsb1;
|
chsb2=Classes[i].hsb2;
|
kPosition[i]=Calk(hsb1,chsb1,chsb2);
|
lastCheckedClass=i;
|
}
|
for (i=0;i<lastCheckedClass;i++)
|
{
|
if (!Classes[i].isChecked) {continue;}
|
if (kPosition[i]<0) {n=kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i].N1;;break;}
|
if (i==lastCheckedClass-1) {n=kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i].N1;break;}
|
if (kPosition[i]>=0&&kPosition[i]<=1&&kPosition[i+1]<0) {n=kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i].N1;break;}
|
if (kPosition[i]>=0&&kPosition[i]<=1&&kPosition[i+1]>=0&&kPosition[i+1]<=1) {n=(kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i+1].N1+kPosition[i+1]*(Classes[i+1].N2-Classes[i+1].N1)+Classes[i+1].N1)/2;break;}
|
if (kPosition[i]>1&&kPosition[i+1]<0)
|
{
|
n=Classes[i].N2;break;
|
}
|
}
|
return n;
|
}
|
*/
|
/*
|
for (i=0;i<pt1total-1;i++) //ÑéÖ¤ËùÓеĵãÊDz»ÊǶ¼ÔÚÒ»ÌõÏßÉÏ¡£
|
{
|
startpt1=i;
|
pt1valid[i]=1;
|
continuepts1=2; //ÔÚÒ»ÌõÏßÉϵĵãµÄÊýÁ¿£¬×ʼµÄÁ½¸öµã¿Ï¶¨ÔÚͬһÌõÏßÉÏ¡£
|
|
for (j=i+1;j<pt1total;j++)
|
{
|
|
continuepts1=2; //ÔÚÒ»ÌõÏßÉϵĵãµÄÊýÁ¿£¬×ʼµÄÁ½¸öµã¿Ï¶¨ÔÚͬһÌõÏßÉÏ¡£
|
pt1valid[j]=1;
|
angle1=atan(((double)pt1[i].x-pt1[j].x)/((double)pt1[i].y-pt1[j].y));
|
endpt1=j;
|
for (k=j+1;k<pt1total;k++)
|
{
|
|
angle2=atan(((double)pt1[i].x-pt1[k].x)/((double)pt1[i].y-pt1[k].y));
|
distance=sqrt((double)(pt1[i].x-pt1[k].x)*(pt1[i].x-pt1[k].x)+(pt1[i].y-pt1[k].y)*(pt1[i].y-pt1[k].y));
|
intercept=distance*sin(abs(angle2-angle1));
|
//À뿪ֱÏߵľàÀ룬½Ø¾à;
|
//if (abs(angle1-angle2)<maxangle) //Èç¹ûÓëµÚÒ»¸öµãµÄ½Ç¶ÈºÍÔÀ´µÄ½Ç¶ÈÔÚÒ»¶¨·¶Î§ÄÚ£¬ÈÏΪÔÚÒ»ÌõÏßÉÏ¡£
|
if (intercept<maxintercept)
|
{
|
pt1valid[k]=1;
|
endpt1=k;
|
continuepts1++;
|
}
|
else
|
{
|
pt1valid[k]=0;
|
}
|
}
|
|
if (continuepts1>=4) //Èç¹ûÔÚ3¸öµã»òÒÔÉÏÔÚͬһÌõÏßÉÏ£¬ÈÏΪÊÇÒ»ÌõÓÐЧµÄÏß¡£
|
{
|
line1found=1;
|
break;
|
}
|
else //·ñÔòÖØÐÂÕÒÏß¡£
|
{
|
pt1valid[j]=0;
|
for (k=j+1;k<pt1total;k++)
|
{
|
pt1valid[k]=0;
|
}
|
}
|
}
|
if (line1found) {break;}
|
pt1valid[i]=0;
|
}
|
*/
|
int BayerGR8toRGB32(void * src,void * dest,int width,int height,int stride1,int stride2)
|
{
|
int w=width,h=height;
|
// unsigned char * srcpixel=(unsigned char *)srcbuf;
|
// DWORD * pixels=(DWORD *)destbuf;
|
|
|
//unsigned short R,G,B,R1,R2,R3,R4,G1,G2,G3,G4,B1,B2,B3,B4;
|
|
|
DWORD * destbuf=(DWORD *) dest;
|
unsigned char * srcbuf=(unsigned char *)src;
|
// s=width;
|
DWORD w2=stride2/4;
|
|
|
#pragma omp parallel for
|
for (int i=2;i<height-4;i+=2)
|
{
|
unsigned char G00, B01, G02, B03, G04, B05;
|
unsigned char R10, G11, R12, G13, R14, G15;
|
unsigned char G20, B21, G22, B23, G24, B25;
|
unsigned char R30, G31, R32, G33, R34, G35;
|
unsigned char G40, B41, G42, B43, G44, B45;
|
unsigned char R50, G51, R52, G53, R54, G55;
|
|
COLOR pixel;
|
unsigned char *line0=srcbuf+i*stride1-stride1-stride1;
|
unsigned char *line1=srcbuf+i*stride1-stride1;
|
unsigned char *line2=srcbuf+i*stride1;
|
unsigned char *line3=srcbuf+i*stride1+stride1;
|
unsigned char *line4=srcbuf+i*stride1+stride1+stride1;
|
unsigned char *line5=srcbuf+i*stride1+stride1+stride1+stride1;
|
int ll=i*w2;
|
int lll=i*w2+w2;
|
for (int j=2;j<width-4;j+=2)
|
{
|
// ÆæÊýÐÐ
|
|
pixel.R=(line2[j-1]+line2[j+1])/2;
|
pixel.G=line2[j];
|
pixel.B=(line1[j]+line3[j])/2;
|
((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
|
|
pixel.R=line2[j+1];
|
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
//else{pixel.G=(G22+G24)/2;}
|
if (abs(signed(line0[j+1]+line4[j+1]-line2[j+1]*2))<abs(signed(line2[j-1]+line2[j+3]-line2[j+1]*2))) { pixel.G=(line1[j+1]+line3[j+1])/2; }
|
else { pixel.G=(line2[j]+line2[j+2])/2; }
|
|
pixel.B=((unsigned int )line1[j]+line3[j]+line1[j+2]+line3[j+2])/4;
|
destbuf[ll+j+1]=pixel.argb ;
|
|
//żÊýÐÐ
|
pixel.R=((unsigned int )line2[j-1]+line4[j-1]+line2[j+1]+line4[j+1])/4;
|
// if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
// else{pixel.G=(G31+G33)/2;}
|
if (abs(signed(line1[j]+line5[j]-line3[j]*2))<abs(signed(line3[j-2]+line3[j+2]-line3[j]*2))) { pixel.G=(line2[j]+line4[j])/2; }
|
else { pixel.G=(line3[j-1]+line3[j+1])/2; }
|
pixel.B=line3[j];
|
destbuf[lll+j]=pixel.argb ;
|
|
pixel.R=(line2[j+1]+line4[j+1])/2;
|
pixel.G=line3[j+1];
|
pixel.B=(line3[j]+line3[j+2])/2;
|
destbuf[lll+j+1]=pixel.argb ;
|
}
|
|
continue;
|
|
int k,l,m,n,p,q;//,s;
|
|
k=i*stride1-stride1-stride1; //ÉÏÒ»ÐÐ
|
l=i*stride1-stride1; //µ±Ç°ÐÐ
|
m=i*stride1; //ÏÂÒ»ÐÐ
|
n=m+stride1; //ÏÂÁ½ÐÐ
|
p=m+stride1+stride1;
|
q=m+stride1+stride1+stride1;
|
B01=srcbuf[k+1];G02=srcbuf[k+2];B03=srcbuf[k+3];G04=srcbuf[k+4];B05=srcbuf[k+5];
|
R10=srcbuf[l+0];G11=srcbuf[l+1];R12=srcbuf[l+2];G13=srcbuf[l+3];R14=srcbuf[l+4];G15=srcbuf[l+5];
|
G20=srcbuf[m+0];B21=srcbuf[m+1];G22=srcbuf[m+2];B23=srcbuf[m+3];G24=srcbuf[m+4];B25=srcbuf[m+5];
|
R30=srcbuf[n+0];G31=srcbuf[n+1];R32=srcbuf[n+2];G33=srcbuf[n+3];R34=srcbuf[n+4];G35=srcbuf[n+5];
|
G40=srcbuf[p+0];B41=srcbuf[p+1];G42=srcbuf[p+2];B43=srcbuf[p+3];G44=srcbuf[p+4];B45=srcbuf[p+5];
|
R50=srcbuf[q+0];G51=srcbuf[q+1];R52=srcbuf[q+2];G53=srcbuf[q+3];R54=srcbuf[q+4];G55=srcbuf[q+5];
|
|
for (int j=2;j<width-4;j+=2)
|
{
|
// ÆæÊýÐÐ
|
|
/*B01=srcbuf[k+j-1];*/G02=srcbuf[k+j+0];B03=srcbuf[k+j+1];//G04=srcbuf[k+j+2];B05=srcbuf[k+j+3];
|
/*R10=srcbuf[l+j-2];*/G11=srcbuf[l+j-1];R12=srcbuf[l+j+0];G13=srcbuf[l+j+1];R14=srcbuf[l+j+2];//G15=srcbuf[l+j+3];
|
G20=srcbuf[m+j-2];B21=srcbuf[m+j-1];G22=srcbuf[m+j+0];B23=srcbuf[m+j+1];G24=srcbuf[m+j+2];B25=srcbuf[m+j+3];
|
R30=srcbuf[n+j-2];G31=srcbuf[n+j-1];R32=srcbuf[n+j+0];G33=srcbuf[n+j+1];R34=srcbuf[n+j+2];G35=srcbuf[n+j+3];
|
/*G40=srcbuf[p+j-2];*/B41=srcbuf[p+j-1];G42=srcbuf[p+j+0];B43=srcbuf[p+j+1];G44=srcbuf[p+j+2];//B45=srcbuf[p+j+3];
|
/*R50=srcbuf[q+j-2];G51=srcbuf[q+j-1];*/R52=srcbuf[q+j+0];G53=srcbuf[q+j+1];//R54=srcbuf[q+j+2];G35=srcbuf[q+j+3];
|
|
pixel.R=(B21+B23)/2;
|
pixel.G=G22;
|
pixel.B=(R12+R32)/2;
|
((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
|
|
pixel.R=B23;
|
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
//else{pixel.G=(G22+G24)/2;}
|
if (abs(signed(B03+B43-B23*2))<abs(signed(B21+B25-B23*2))) { pixel.G=(G13+G33)/2; }
|
else { pixel.G=(G22+G24)/2; }
|
|
pixel.B=((unsigned int )R12+R32+R14+R34)/4;
|
destbuf[i*w2+j+1]=pixel.argb ;
|
|
//żÊýÐÐ
|
pixel.R=((unsigned int )B21+B41+B23+B43)/4;
|
// if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
// else{pixel.G=(G31+G33)/2;}
|
if (abs(signed(R12+R52-R32*2))<abs(signed(R30+R34-R32*2))) { pixel.G=(G22+G42)/2; }
|
else { pixel.G=(G31+G33)/2; }
|
pixel.B=R32;
|
destbuf[i*w2+w2+j]=pixel.argb ;
|
|
pixel.R=(B23+B43)/2;
|
pixel.G=G33;
|
pixel.B=(R32+R34)/2;
|
destbuf[i*w2+w2+j+1]=pixel.argb ;
|
}
|
}
|
return 0;
|
|
/*
|
|
for (int i=0;i<h;i+=2)
|
{
|
COLOR c1;
|
int k=i*(int)stride1;
|
//żÊýÐÐ
|
int l=i*stride2/4;
|
for (int j=0;j<w;j+=2)
|
{
|
c1.G=srcpixel[k+j];
|
c1.B=srcpixel[k+j+1];
|
c1.R=srcpixel[k+stride1+j];
|
pixels[l+j]=c1.argb;
|
pixels[l+j+1]=c1.argb;
|
}
|
//ÆæÊýÐÐ
|
l=(i+1)*stride2/4;
|
for (int j=0;j<w;j+=2)
|
{
|
c1.G=srcpixel[k+stride1+j+1];
|
c1.B=srcpixel[k+j+1];
|
c1.R=srcpixel[k+stride1+j];
|
pixels[l+j]=c1.argb;
|
pixels[l+j+1]=c1.argb;
|
}
|
}
|
return 1;
|
*/
|
}
|
int BayerGB8toRGB32(void * src,void * dest,int width,int height,int stride1,int stride2)
|
{
|
int w=width,h=height;
|
// unsigned char * srcpixel=(unsigned char *)srcbuf;
|
// DWORD * pixels=(DWORD *)destbuf;
|
|
|
//unsigned short R,G,B,R1,R2,R3,R4,G1,G2,G3,G4,B1,B2,B3,B4;
|
|
|
DWORD * destbuf=(DWORD *) dest;
|
unsigned char * srcbuf=(unsigned char *)src;
|
// s=width;
|
DWORD w2=stride2/4;
|
|
|
#pragma omp parallel for
|
for (int i=2;i<height-4;i+=2)
|
{
|
unsigned char G00, B01, G02, B03, G04, B05;
|
unsigned char R10, G11, R12, G13, R14, G15;
|
unsigned char G20, B21, G22, B23, G24, B25;
|
unsigned char R30, G31, R32, G33, R34, G35;
|
unsigned char G40, B41, G42, B43, G44, B45;
|
unsigned char R50, G51, R52, G53, R54, G55;
|
|
COLOR pixel;
|
unsigned char *line0=srcbuf+i*stride1-stride1-stride1;
|
unsigned char *line1=srcbuf+i*stride1-stride1;
|
unsigned char *line2=srcbuf+i*stride1;
|
unsigned char *line3=srcbuf+i*stride1+stride1;
|
unsigned char *line4=srcbuf+i*stride1+stride1+stride1;
|
unsigned char *line5=srcbuf+i*stride1+stride1+stride1+stride1;
|
|
for (int j=2;j<width-4;j+=2)
|
{
|
// ÆæÊýÐÐ
|
|
pixel.B=(line2[j-1]+line2[j+1])/2;
|
pixel.G=line2[j];
|
pixel.R=(line1[j]+line3[j])/2;
|
((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
|
|
pixel.B=line2[j+1];
|
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
//else{pixel.G=(G22+G24)/2;}
|
if (abs(signed(line0[j+1]+line4[j+1]-line2[j+1]*2))<abs(signed(line2[j-1]+line2[j+3]-line2[j+1]*2))) { pixel.G=(line1[j+1]+line3[j+1])/2; }
|
else { pixel.G=(line2[j]+line2[j+2])/2; }
|
|
pixel.R=((unsigned int )line1[j]+line3[j]+line1[j+2]+line3[j+2])/4;
|
destbuf[i*w2+j+1]=pixel.argb ;
|
|
//żÊýÐÐ
|
pixel.B=((unsigned int )line2[j-1]+line4[j-1]+line2[j+1]+line4[j+1])/4;
|
// if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
// else{pixel.G=(G31+G33)/2;}
|
if (abs(signed(line1[j]+line5[j]-line3[j]*2))<abs(signed(line3[j-2]+line3[j+2]-line3[j]*2))) { pixel.G=(line2[j]+line4[j])/2; }
|
else { pixel.G=(line3[j-1]+line3[j+1])/2; }
|
pixel.R=line3[j];
|
destbuf[i*w2+w2+j]=pixel.argb ;
|
|
pixel.B=(line2[j+1]+line4[j+1])/2;
|
pixel.G=line3[j+1];
|
pixel.R=(line3[j]+line3[j+2])/2;
|
destbuf[i*w2+w2+j+1]=pixel.argb ;
|
}
|
|
continue;
|
|
int k,l,m,n,p,q;//,s;
|
|
k=i*stride1-stride1-stride1; //ÉÏÒ»ÐÐ
|
l=i*stride1-stride1; //µ±Ç°ÐÐ
|
m=i*stride1; //ÏÂÒ»ÐÐ
|
n=m+stride1; //ÏÂÁ½ÐÐ
|
p=m+stride1+stride1;
|
q=m+stride1+stride1+stride1;
|
B01=srcbuf[k+1];G02=srcbuf[k+2];B03=srcbuf[k+3];G04=srcbuf[k+4];B05=srcbuf[k+5];
|
R10=srcbuf[l+0];G11=srcbuf[l+1];R12=srcbuf[l+2];G13=srcbuf[l+3];R14=srcbuf[l+4];G15=srcbuf[l+5];
|
G20=srcbuf[m+0];B21=srcbuf[m+1];G22=srcbuf[m+2];B23=srcbuf[m+3];G24=srcbuf[m+4];B25=srcbuf[m+5];
|
R30=srcbuf[n+0];G31=srcbuf[n+1];R32=srcbuf[n+2];G33=srcbuf[n+3];R34=srcbuf[n+4];G35=srcbuf[n+5];
|
G40=srcbuf[p+0];B41=srcbuf[p+1];G42=srcbuf[p+2];B43=srcbuf[p+3];G44=srcbuf[p+4];B45=srcbuf[p+5];
|
R50=srcbuf[q+0];G51=srcbuf[q+1];R52=srcbuf[q+2];G53=srcbuf[q+3];R54=srcbuf[q+4];G55=srcbuf[q+5];
|
|
for (int j=2;j<width-4;j+=2)
|
{
|
// ÆæÊýÐÐ
|
|
/*B01=srcbuf[k+j-1];*/G02=srcbuf[k+j+0];B03=srcbuf[k+j+1];//G04=srcbuf[k+j+2];B05=srcbuf[k+j+3];
|
/*R10=srcbuf[l+j-2];*/G11=srcbuf[l+j-1];R12=srcbuf[l+j+0];G13=srcbuf[l+j+1];R14=srcbuf[l+j+2];//G15=srcbuf[l+j+3];
|
G20=srcbuf[m+j-2];B21=srcbuf[m+j-1];G22=srcbuf[m+j+0];B23=srcbuf[m+j+1];G24=srcbuf[m+j+2];B25=srcbuf[m+j+3];
|
R30=srcbuf[n+j-2];G31=srcbuf[n+j-1];R32=srcbuf[n+j+0];G33=srcbuf[n+j+1];R34=srcbuf[n+j+2];G35=srcbuf[n+j+3];
|
/*G40=srcbuf[p+j-2];*/B41=srcbuf[p+j-1];G42=srcbuf[p+j+0];B43=srcbuf[p+j+1];G44=srcbuf[p+j+2];//B45=srcbuf[p+j+3];
|
/*R50=srcbuf[q+j-2];G51=srcbuf[q+j-1];*/R52=srcbuf[q+j+0];G53=srcbuf[q+j+1];//R54=srcbuf[q+j+2];G35=srcbuf[q+j+3];
|
|
pixel.B=(B21+B23)/2;
|
pixel.G=G22;
|
pixel.R=(R12+R32)/2;
|
((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
|
|
pixel.B=B23;
|
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
//else{pixel.G=(G22+G24)/2;}
|
if (abs(signed(B03+B43-B23*2))<abs(signed(B21+B25-B23*2))) { pixel.G=(G13+G33)/2; }
|
else { pixel.G=(G22+G24)/2; }
|
|
pixel.R=((unsigned int )R12+R32+R14+R34)/4;
|
destbuf[i*w2+j+1]=pixel.argb ;
|
|
//żÊýÐÐ
|
pixel.B=((unsigned int )B21+B41+B23+B43)/4;
|
// if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
// else{pixel.G=(G31+G33)/2;}
|
if (abs(signed(R12+R52-R32*2))<abs(signed(R30+R34-R32*2))) { pixel.G=(G22+G42)/2; }
|
else { pixel.G=(G31+G33)/2; }
|
pixel.R=R32;
|
destbuf[i*w2+w2+j]=pixel.argb ;
|
|
pixel.B=(B23+B43)/2;
|
pixel.G=G33;
|
pixel.R=(R32+R34)/2;
|
destbuf[i*w2+w2+j+1]=pixel.argb ;
|
}
|
}
|
return 0;
|
|
/*
|
|
for (int i=0;i<h;i+=2)
|
{
|
COLOR c1;
|
int k=i*(int)stride1;
|
//żÊýÐÐ
|
int l=i*stride2/4;
|
for (int j=0;j<w;j+=2)
|
{
|
c1.G=srcpixel[k+j];
|
c1.B=srcpixel[k+j+1];
|
c1.R=srcpixel[k+stride1+j];
|
pixels[l+j]=c1.argb;
|
pixels[l+j+1]=c1.argb;
|
}
|
//ÆæÊýÐÐ
|
l=(i+1)*stride2/4;
|
for (int j=0;j<w;j+=2)
|
{
|
c1.G=srcpixel[k+stride1+j+1];
|
c1.B=srcpixel[k+j+1];
|
c1.R=srcpixel[k+stride1+j];
|
pixels[l+j]=c1.argb;
|
pixels[l+j+1]=c1.argb;
|
}
|
}
|
return 1;
|
*/
|
}
|
int BayerGB8toRGB24(void * srcbuf,void * destbuf,int width,int height,int stride,int stride2)
|
{
|
int w=width,h=height;
|
int Stride=stride;
|
int s=stride2;
|
unsigned char * srcpixel=(unsigned char *)srcbuf;
|
unsigned char * pixels=(unsigned char *)destbuf;
|
|
#pragma omp parallel for
|
for (int i=0;i<h;i+=2)
|
{
|
COLOR c1;
|
int k=i*(int)Stride;
|
//żÊýÐÐ
|
int l=i*s;
|
for (int j=0;j<w;j+=2)
|
{
|
c1.G=srcpixel[k+j];
|
c1.B=srcpixel[k+j+1];
|
c1.R=srcpixel[k+Stride+j];
|
pixels[l+(j)*3+0]=c1.B; pixels[l+(j)*3+1]=c1.G; pixels[l+(j)*3+2]=c1.R;
|
pixels[l+(j+1)*3+0]=c1.B; pixels[l+(j+1)*3+1]=c1.G; pixels[l+(j+1)*3+2]=c1.R;
|
}
|
//ÆæÊýÐÐ
|
l=(i+1)*s;
|
for (int j=0;j<w;j+=2)
|
{
|
c1.G=srcpixel[k+Stride+j+1];
|
c1.B=srcpixel[k+j+1];
|
c1.R=srcpixel[k+Stride+j];
|
pixels[l+(j)*3+0]=c1.B; pixels[l+(j)*3+1]=c1.G; pixels[l+(j)*3+2]=c1.R;
|
pixels[l+(j+1)*3+0]=c1.B; pixels[l+(j+1)*3+1]=c1.G; pixels[l+(j+1)*3+2]=c1.R;
|
}
|
}
|
return 1;
|
}
|
|
int SecWhiteBalance::LoadWBParamFromFile(CString sFilePathName)
|
{
|
CString s1;
|
// s1.Format(_T("´ÓÎļþ %s ¼ÓÔØ°×ƽºâ½ÃÕýÄ£°å \r\n"),sFilePathName);
|
// SysLog(s1);
|
int j=0;
|
Gdiplus::Bitmap bitmap1(sFilePathName);
|
|
if (bitmap1.GetWidth()!=0)
|
{j=ReadWBParamFromBmp(&bitmap1);}
|
return j;
|
}
|
|
int SecWhiteBalance::ReadWBParamFromBmp(Gdiplus::Bitmap * bitmap1)
|
{
|
|
// double tick0=GetTickCountmS();
|
if (bitmap1==NULL) {return 0;}
|
if (bitmap1->GetWidth()==0||bitmap1->GetHeight()==0) {return 0;}
|
int i,j,k;
|
int w,h;
|
w=bitmap1->GetWidth();
|
h=bitmap1->GetHeight();
|
if (0==w||0==h)
|
{return 0;}
|
|
Gdiplus::BitmapData bitmapdata0;
|
UINT * pixels;
|
Gdiplus::Rect rect0(0,0,w,h);
|
|
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapdata0);
|
if (GdipStatus!=Gdiplus::Ok)
|
{
|
CString Errs1;
|
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
// SysLog(Errs1);
|
return 0;
|
}
|
pixels=(UINT *)bitmapdata0.Scan0 ;
|
|
// xsecs=w/xstep;
|
// ysecs=h/ystep;
|
// int m,n;
|
COLOR c1;
|
// int secR,secG,secB,secV;
|
// float aveR,aveG,aveB,aveV;
|
float totalaveR,totalaveG,totalaveB;
|
totalaveR=0;totalaveG=0;totalaveB=0;
|
for (i=0;i<wbysecs;i++)
|
{
|
for (j=0;j<wbxsecs;j++)
|
{
|
wbsectotalR[i][j]=0;
|
wbsectotalG[i][j]=0;
|
wbsectotalB[i][j]=0;
|
wbsecsamples[i][j]=0;
|
}
|
}
|
int xsec,ysec;
|
for (i=0;i<h;i++)
|
{
|
k=i*w;
|
ysec=i*wbysecs/h;
|
for (j=0;j<w;j++)
|
{
|
xsec=j*wbxsecs/w;
|
c1.argb =pixels[k+j];
|
wbsectotalR[ysec][xsec]+=c1.R;
|
wbsectotalG[ysec][xsec]+=c1.G;
|
wbsectotalB[ysec][xsec]+=c1.B;
|
wbsecsamples[ysec][xsec]++;
|
}
|
}
|
float wbV;
|
wbtotalV=0;
|
for (i=0;i<wbysecs;i++)
|
{
|
for (j=0;j<wbxsecs;j++)
|
{
|
wbsecR[i][j]=(float)wbsectotalR[i][j]/wbsecsamples[i][j];
|
wbsecG[i][j]=(float)wbsectotalG[i][j]/wbsecsamples[i][j];
|
wbsecB[i][j]=(float)wbsectotalB[i][j]/wbsecsamples[i][j];
|
//wbV=wbsecR[i][j]*0.299f+wbsecG[i][j]*0.587f+wbsecB[i][j]*0.114f;
|
wbV=RGBtoVf(wbsecR[i][j],wbsecG[i][j],wbsecB[i][j]);
|
wbtotalV+=wbV;
|
}
|
}
|
wbaveV=wbtotalV/(wbysecs*wbxsecs);
|
// wbaveV=128.0f;
|
/*
|
for (i=0;i<ysecs;i++)
|
{ yoff=i*ystep*w;
|
for (j=0;j<xsecs;j++)
|
{
|
xoff=j*xstep;
|
secV=0;
|
secR=0;secG=0;secB=0;
|
for(k=0;k<ystep;k++)
|
{
|
m=yoff+k*w;
|
for (l=0;l<xstep;l++)
|
{
|
secR+=c1.R ;
|
secG+=c1.G;
|
secB+=c1.B;
|
}
|
}
|
aveR=(float)secR/(xstep*ystep);
|
aveG=(float)secG/(xstep*ystep);
|
aveB=(float)secB/(xstep*ystep);
|
|
aveV=secV/(xstep*ystep);
|
bright[i][j]=aveV;
|
wbR[i][j]=aveR;
|
wbG[i][j]=aveG;
|
wbB[i][j]=aveB;
|
totalaveR+=aveR;
|
totalaveG+=aveG;
|
totalaveB+=aveB;
|
}
|
}
|
//*/
|
bitmap1->UnlockBits(&bitmapdata0);
|
// double tick1=GetTickCountmS();
|
|
CString s1;
|
// s1.Format(_T("´´½¨°×ƽºâÊý×飬w,h %d %d ÓÃʱ %.2fmS\r\n"),w,h,tick1-tick0);
|
// SysLog(s1);
|
wbcorrloaded=1;
|
autowbcorronopen=1;
|
|
// ((CButton *)GetDlgItem(IDC_CHECK_WBCORR))->SetCheck(true);
|
|
return 1;
|
}
|
|
int SecWhiteBalance::LoadBayerWBParamFromFile(CString sFilePathName)
|
{
|
CString s1;
|
// s1.Format(_T("´ÓÎļþ %s ¼ÓÔØ°×ƽºâ½ÃÕýÄ£°å \r\n"),sFilePathName);
|
// SysLog(s1);
|
int j=0;
|
Gdiplus::Bitmap bitmap1(sFilePathName);
|
|
if (bitmap1.GetWidth()!=0)
|
{j=ReadBayerWBParamFromBmp(&bitmap1);}
|
return j;
|
}
|
int SecWhiteBalance::ReadBayerWBParamFromBmp(Gdiplus::Bitmap * bitmap1)
|
{
|
|
// double tick0=GetTickCountmS();
|
if (bitmap1==NULL) {return 0;}
|
if (bitmap1->GetWidth()==0||bitmap1->GetHeight()==0) {return 0;}
|
int i,j,k;
|
int w,h;
|
w=bitmap1->GetWidth();
|
h=bitmap1->GetHeight();
|
if (0==w||0==h)
|
{return 0;}
|
|
Gdiplus::BitmapData bitmapdata0;
|
unsigned char * pixels;
|
Gdiplus::Rect rect0(0,0,w,h);
|
|
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat8bppIndexed,&bitmapdata0);
|
if (GdipStatus!=Gdiplus::Ok)
|
{
|
CString Errs1;
|
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
// SysLog(Errs1);
|
return 0;
|
}
|
pixels=(unsigned char *)bitmapdata0.Scan0 ;
|
int stride=bitmapdata0.Stride;
|
// xsecs=w/xstep;
|
// ysecs=h/ystep;
|
// int m,n;
|
//COLOR c1;
|
|
// int secR,secG,secB,secV;
|
// float aveR,aveG,aveB,aveV;
|
float totalaveR,totalaveG,totalaveB;
|
totalaveR=0;totalaveG=0;totalaveB=0;
|
for (i=0;i<wbysecs;i++)
|
{
|
for (j=0;j<wbxsecs;j++)
|
{
|
wbsectotalR[i][j]=0;
|
wbsectotalG[i][j]=0;
|
wbsectotalB[i][j]=0;
|
wbsecsamples[i][j]=0;
|
}
|
}
|
int xsec,ysec;
|
for (i=0;i<h;i+=2)
|
{
|
k=i*stride;
|
ysec=i*wbysecs/h;
|
for (j=0;j<w;j+=2)
|
{
|
xsec=j*wbxsecs/w;
|
unsigned char c1,c2,c3,c4;
|
c1 = pixels[k+j];
|
c2 = pixels[k+j+1];
|
c3 = pixels[k+stride+j];
|
c4 = pixels[k+stride+j+1];
|
|
wbsectotalG[ysec][xsec]+=c1;
|
wbsectotalR[ysec][xsec]+=c2;
|
wbsectotalB[ysec][xsec]+=c3;
|
wbsectotalG2[ysec][xsec]+=c4;
|
wbsecsamples[ysec][xsec]++;
|
}
|
}
|
bitmap1->UnlockBits(&bitmapdata0);
|
float wbV;
|
wbtotalV=0;
|
for (i=0;i<wbysecs;i++)
|
{
|
for (j=0;j<wbxsecs;j++)
|
{
|
wbsecR[i][j]=(float)wbsectotalR[i][j]/wbsecsamples[i][j];
|
wbsecG[i][j]=(float)wbsectotalG[i][j]/wbsecsamples[i][j];
|
wbsecB[i][j]=(float)wbsectotalB[i][j]/wbsecsamples[i][j];
|
wbsecG2[i][j]=(float)wbsectotalG2[i][j]/wbsecsamples[i][j];
|
//wbV=wbsecR[i][j]*0.299f+wbsecG[i][j]*0.587f+wbsecB[i][j]*0.114f;
|
wbV=RGBtoVf(wbsecR[i][j],wbsecG[i][j],wbsecB[i][j]);
|
wbtotalV+=wbV;
|
}
|
}
|
wbaveV=wbtotalV/(wbysecs*wbxsecs);
|
/* ±£´æ³ÉÒ»¸öBMP
|
Bitmap bitmap2(wbxsecs,wbysecs);
|
BitmapData bitmapdata2;
|
bitmap2.LockBits(&Rect(0,0,wbxsecs,wbysecs),ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata2);
|
UINT * pixels2=(UINT *)bitmapdata2.Scan0;
|
int stride2=bitmapdata2.Stride;
|
for (int i=0;i<wbysecs;i++)
|
{
|
for (int j=0;j<wbxsecs;j++)
|
{
|
COLOR c2;
|
c2.R=wbsecR[i][j];
|
c2.G=wbsecG[i][j];
|
c2.B=wbsecB[i][j];
|
pixels2[i*stride2/4+j]=c2.argb;
|
}
|
}
|
bitmap2.UnlockBits(&bitmapdata2);
|
SaveGdiPImageAsFile(&bitmap2,_T("D:\\1\\aa.bmp"));
|
*/
|
BrightnessCorr=1.0f;
|
for (i=0;i<wbysecs;i++)
|
{
|
for (j=0;j<wbxsecs;j++)
|
{
|
float wbR=wbsecR[i][j];
|
float wbG=wbsecG[i][j];
|
float wbB=wbsecB[i][j];
|
float wbG2=wbsecG2[i][j];
|
if (wbR<32) {wbR=32;}
|
if (wbG<32) {wbG=32;}
|
if (wbB<32) {wbB=32;}
|
if (wbG2<32) {wbG2=32;}
|
float wbRcorr,wbGcorr,wbBcorr,wbG2corr;
|
|
if (TargetLight==0)
|
{
|
wbRcorr=int(128.0f*wbaveV*BrightnessCorr/wbR);
|
wbGcorr=int(128.0f*wbaveV*BrightnessCorr/wbG);
|
wbBcorr=int(128.0f*wbaveV*BrightnessCorr/wbB);
|
wbG2corr=int(128.0f*wbaveV*BrightnessCorr/wbG2);
|
}
|
else if (TargetLightR*TargetLightG*TargetLightB==0)
|
{
|
wbRcorr=int(128.0f*TargetLight*BrightnessCorr/wbR);
|
wbGcorr=int(128.0f*TargetLight*BrightnessCorr/wbG);
|
wbBcorr=int(128.0f*TargetLight*BrightnessCorr/wbB);
|
wbG2corr=int(128.0f*TargetLight*BrightnessCorr/wbG2);
|
}else
|
{
|
wbRcorr=int(128.0f*TargetLightR*BrightnessCorr/wbR);
|
wbGcorr=int(128.0f*TargetLightG*BrightnessCorr/wbG);
|
wbBcorr=int(128.0f*TargetLightB*BrightnessCorr/wbB);
|
wbG2corr=int(128.0f*TargetLightG*BrightnessCorr/wbG2);
|
}
|
wbsecRcorr[i][j]=wbRcorr;
|
wbsecGcorr[i][j]=wbGcorr;
|
wbsecBcorr[i][j]=wbBcorr;
|
wbsecG2corr[i][j]=wbG2corr;
|
}
|
}
|
/*
|
Bitmap bitmap3(wbxsecs,wbysecs);
|
BitmapData bitmapdata3;
|
bitmap3.LockBits(&Rect(0,0,wbxsecs,wbysecs),ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata3);
|
UINT * pixels3=(UINT *)bitmapdata3.Scan0;
|
int stride3=bitmapdata3.Stride;
|
for (int i=0;i<wbysecs;i++)
|
{
|
for (int j=0;j<wbxsecs;j++)
|
{
|
COLOR c2;
|
c2.R=wbsecRcorr[i][j];
|
c2.G=wbsecGcorr[i][j];
|
c2.B=wbsecBcorr[i][j];
|
pixels3[i*stride3/4+j]=c2.argb;
|
}
|
}
|
bitmap3.UnlockBits(&bitmapdata3);
|
SaveGdiPImageAsFile(&bitmap3,_T("D:\\1\\aa3.bmp"));
|
*/
|
// wbaveV=128.0f;
|
/*
|
for (i=0;i<ysecs;i++)
|
{ yoff=i*ystep*w;
|
for (j=0;j<xsecs;j++)
|
{
|
xoff=j*xstep;
|
secV=0;
|
secR=0;secG=0;secB=0;
|
for(k=0;k<ystep;k++)
|
{
|
m=yoff+k*w;
|
for (l=0;l<xstep;l++)
|
{
|
secR+=c1.R ;
|
secG+=c1.G;
|
secB+=c1.B;
|
}
|
}
|
aveR=(float)secR/(xstep*ystep);
|
aveG=(float)secG/(xstep*ystep);
|
aveB=(float)secB/(xstep*ystep);
|
|
aveV=secV/(xstep*ystep);
|
bright[i][j]=aveV;
|
wbR[i][j]=aveR;
|
wbG[i][j]=aveG;
|
wbB[i][j]=aveB;
|
totalaveR+=aveR;
|
totalaveG+=aveG;
|
totalaveB+=aveB;
|
}
|
}
|
//*/
|
|
// double tick1=GetTickCountmS();
|
|
CString s1;
|
// s1.Format(_T("´´½¨°×ƽºâÊý×飬w,h %d %d ÓÃʱ %.2fmS\r\n"),w,h,tick1-tick0);
|
// SysLog(s1);
|
wbcorrloaded=1;
|
autowbcorronopen=1;
|
|
// ((CButton *)GetDlgItem(IDC_CHECK_WBCORR))->SetCheck(true);
|
|
return 1;
|
}
|
|
int SecWhiteBalance::WBCorrect(Gdiplus::Bitmap * bitmap1,Gdiplus::Bitmap * bitmap2,float fRateV, float fRateR, float fRateG, float fRateB)
|
{
|
return WBCorrectVC(bitmap1,bitmap2, fRateR, fRateG, fRateB);
|
}
|
//
|
// int SecWhiteBalance::WBCorrect1(Gdiplus::Bitmap * bitmap1)
|
// {
|
// if (this->wbcorrloaded==0) {return 0;}
|
// double tick0=GetTickCountmS();
|
// int i,j,k;
|
// if (bitmap1==NULL)
|
// {return 0;}
|
// int w,h;
|
// w=bitmap1->GetWidth();
|
// h=bitmap1->GetHeight();
|
// if (0==w||0==h)
|
// {return 0;}
|
// Gdiplus::BitmapData bitmapdata0;
|
// UINT * pixels;
|
// Gdiplus::Rect rect0(0,0,w,h);
|
// // UINT * pixels2;
|
// COLOR * c2;
|
// Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead|Gdiplus::ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata0);
|
// if (GdipStatus!=Gdiplus::Ok)
|
// {
|
// CString Errs1;
|
// Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
// // SysLog(Errs1);
|
// return 0;
|
// }
|
// pixels=(UINT *)bitmapdata0.Scan0 ;
|
// int s=bitmapdata0.Stride/4;
|
// /*
|
// threadinfo1[0].pParam1=this;
|
// threadinfo1[0].pParam2=0;
|
// threadinfo1[0].starty=0;
|
// threadinfo1[0].endy=wbysecs/2;
|
// threadinfo1[0].pixels=pixels;
|
// threadinfo1[0].h=h;
|
// threadinfo1[0].w=w;
|
// threadinfo1[0].torun=1;
|
// threadinfo1[0].stride=bitmapdata0.Stride;
|
// threadinfo1[0].finish=0;
|
//
|
// threadinfo1[1].pParam1=this;
|
// threadinfo1[1].pParam2=(LPVOID)1;
|
// threadinfo1[1].starty=wbysecs/2;
|
// threadinfo1[1].endy=wbysecs;
|
// threadinfo1[1].pixels=pixels;
|
// threadinfo1[1].h=h;
|
// threadinfo1[1].w=w;
|
// threadinfo1[1].torun=1;
|
// threadinfo1[1].stride=bitmapdata0.Stride;
|
// threadinfo1[1].finish=0;
|
// */
|
// // CWinThread * thread1;
|
// // CWinThread * thread2;
|
// /*
|
// thread1=AfxBeginThread(WBcorrThreadJumper,&(threadinfo1[0]),0,0,CREATE_SUSPENDED,0);
|
// thread2=AfxBeginThread(WBcorrThreadJumper,&(threadinfo1[1]),0,0,CREATE_SUSPENDED,0);
|
// // thread1->m_bAutoDelete=true;
|
// // thread2->m_bAutoDelete=true;
|
// // ::SetThreadAffinityMask(thread1->m_hThread,0x00000001);
|
// // ::SetThreadAffinityMask(thread2->m_hThread,0x00000002);
|
// thread1->ResumeThread();
|
// thread2->ResumeThread();
|
// for (i=0;i<10000;i++)
|
// {
|
// if (threadinfo1[0].finish==0||threadinfo1[1].finish==0)
|
// {
|
// Sleep(10);
|
// }
|
// else
|
// {
|
// break;
|
// }
|
// }
|
// //*/
|
// // int xsec,ysec;
|
// // int m,n;
|
// // COLOR c1;
|
// // int secV;
|
// // int aveV;
|
//
|
// int yoff,ystep,xoff,xstep;
|
// int offset;
|
// float wbR,wbG,wbB;
|
// // short int R,G,B;
|
// short int wbRcorr,wbGcorr,wbBcorr;
|
// // if (0)
|
// for (i=0;i<wbysecs;i++)
|
// { yoff=i*h/wbysecs;
|
// ystep=(i+1)*h/wbysecs-yoff;
|
// for (j=0;j<wbxsecs;j++)
|
// {
|
// xoff=j*w/wbxsecs;
|
// xstep=(j+1)*w/wbxsecs-xoff;
|
// wbR=wbsecR[i][j];
|
// wbG=wbsecG[i][j];
|
// wbB=wbsecB[i][j];
|
// if (wbR<32) {wbR=32;}
|
// if (wbG<32) {wbG=32;}
|
// if (wbB<32) {wbB=32;}
|
// if (TargetLight==0)
|
// {
|
// wbRcorr=int(128.0f*wbaveV*BrightnessCorr/wbR);
|
// wbGcorr=int(128.0f*wbaveV*BrightnessCorr/wbG);
|
// wbBcorr=int(128.0f*wbaveV*BrightnessCorr/wbB);
|
// }
|
// else if (TargetLightR*TargetLightG*TargetLightB==0)
|
// {
|
// wbRcorr=int(128.0f*TargetLight*BrightnessCorr/wbR);
|
// wbGcorr=int(128.0f*TargetLight*BrightnessCorr/wbG);
|
// wbBcorr=int(128.0f*TargetLight*BrightnessCorr/wbB);
|
// }else
|
// {
|
// wbRcorr=int(128.0f*TargetLightR*BrightnessCorr/wbR);
|
// wbGcorr=int(128.0f*TargetLightG*BrightnessCorr/wbG);
|
// wbBcorr=int(128.0f*TargetLightB*BrightnessCorr/wbB);
|
// }
|
// //continue;
|
// // ÉèÖÃÏà³ËϵÊý
|
// /*
|
// __int64 corr = 0;
|
// corr = wbRcorr;
|
// corr = corr << 16;
|
// corr |= wbGcorr;
|
// corr = corr << 16;
|
// corr |= wbBcorr;
|
// _mm_empty(); // Çå¿ÕMMX¼Ä´æÆ÷¡£
|
//
|
// __m64 nNull = _m_from_int(0); // null
|
// __m64 tmp = _m_from_int(0); // ÁÙʱ¹¤×÷ÁÙʱ±äÁ¿³õʼ»¯
|
//
|
// __m64 nCoeff = Get_m64(corr);
|
// __m128 corr128;
|
// corr128.m128_u16[0]=wbBcorr;
|
// corr128.m128_u16[1]=wbGcorr;
|
// corr128.m128_u16[2]=wbRcorr;
|
// corr128.m128_u16[3]=0;
|
// corr128.m128_u16[4]=wbBcorr;
|
// corr128.m128_u16[5]=wbGcorr;
|
// corr128.m128_u16[6]=wbRcorr;
|
// corr128.m128_u16[7]=0;
|
// __m128 nCorr128=corr128;
|
// */
|
// // __m128 nNull128;
|
// // __m128 temp2;
|
//
|
//
|
// // DWORD* pIn = (DWORD*) pSource; // ÊäÈëË«×ÖÊý×é
|
// // DWORD* pOut = (DWORD*) pDest; // Êä³öË«×ÖÊý×é
|
//
|
//
|
// // _mm_set_ps(1.0f,2.0f,3.0f,4.0f);
|
//
|
// for (k=0;k<ystep;k++)
|
// {
|
// offset=(yoff+k)*s+xoff;
|
//
|
// //continue;
|
// c2=(COLOR *)(pixels+offset);
|
// //for (l=0;l<xstep;l++)
|
// {// pixels2=pixels+offset+l;
|
// //continue;
|
// /* ==============//CÓïÑÔ´úÂë =========== 109mS
|
// R=c2->R*wbRcorr>>7;
|
// if (R>255) {c1.R=255;}
|
// else {c2->R=R;}
|
// G=c2->G*wbGcorr>>7;
|
// c2->G=min(255,G);
|
// B=c2->B*wbBcorr>>7;
|
// c2->B =min(255,B);
|
// c2++;
|
// //*/ //========================================
|
//
|
// /* //======================MMX ´úÂë==================================== 120mS
|
// if (usemmx)
|
// {
|
// tmp = _m_from_int(c2->argb); // tmp = *pIn (ÔÚtmpµÄµÍ32λдÈëÊý¾Ý)
|
//
|
// tmp = _mm_unpacklo_pi8(tmp, nNull ); //½«tmpÖеÍλµÄ4¸ö×Ö½Úת»¯Îª×Ö
|
// //×ֵĸßλÓÃnNullÖжÔӦλÉϵÄλֵÌî³ä¡£
|
//
|
// tmp = _mm_mullo_pi16 (tmp , nCoeff); //½«tmpÖеÄÿһ¸ö×ÖÏà³Ë£¬½«Ïà³Ë½á¹ûµÄ¸ßλË͵½nCoeff£¬ÔÚtmpÖÐÖ»±£Áôÿ¸ö½á¹ûµÄµÍλ¡£
|
//
|
// tmp = _mm_srli_pi16 (tmp , 7); // ½«tmpÖеÄÿһ¸ö×ÖÓÒÒÆ7룬Ï൱ÓÚ³ýÒÔ128
|
//
|
// tmp = _mm_packs_pu16 (tmp, nNull); // ʹÓñ¥ºÍģʽ½«tmpÖеĽá¹û×öÈçÏ´¦Àí£º
|
// //½«tmpÖеÄ4¸ö×Öת»¯Îª4¸ö×Ö½Ú£¬²¢½«Õâ4¸ö×Ö½Úдµ½tmpÖеĵÍ32λÖÐ
|
// // ͬʱ£¬½«nNullÖеÄ4¸ö×Öת»¯Îª4¸ö×Ö½Ú£¬²¢½«Õâ4¸ö×Ö½Úдµ½tmpµÄ¸ß32λÖС£
|
//
|
// c2->argb = _m_to_int(tmp)|0xff000000; // *pOut = tmp (½«tmpµÍ32λµÄÊý¾Ý·ÅÈëpOutÊý×éÖÐ)
|
// c2++;
|
// }
|
// //*/ //=======================================================
|
// ////======================= SSE INTRIC ´úÂë ========================
|
// //__m128 a1=_mm_setzero_ps();
|
// //a1=_mm_load
|
// // __m128 a;
|
// // __m128i b;
|
// // __m128d c;
|
// // _mm_packuswb()
|
// ///* //==================== SSE »ã±àÓÅ»¯ ========================== 30mS
|
// int xstep_2=xstep/2;
|
// /*
|
// _asm
|
// {
|
// //tmp=_m_from_int(c2->argb);
|
// //start:
|
// movq xmm0,mmword ptr[nNull];
|
// movdqa xmm4,nCorr128;
|
// mov eax,c2;
|
// sub eax,4;
|
// mov ecx,xstep;
|
// loop1:
|
// //mov edx,dword ptr [eax+ecx*4]
|
// movd xmm1,dword ptr [eax+ecx*4]; //edx;
|
// // movd mm1,dword ptr [eax+ecx*4];
|
// // movq mmword ptr[tmp],mm0;
|
// //tmp=_mm_unpacklo_pi8(tmp,nNull);
|
// //movq xmm0,mmword ptr [nNull];
|
// // movdqa xmm2,xmm0
|
// movaps xmm2,xmm0
|
// // movq mm0,mmword ptr [tmp];
|
// movaps xmm3,xmm4
|
//
|
// punpcklbw xmm1,xmm2;
|
// // movq mmword ptr [tmp],mm1;
|
// // tmp=_mm_mull0_pi16(tmp,nCoeff);
|
// //movdq xmm2,xmmword ptr [nCoeff]
|
// // movdqa xmm2,nCorr128;
|
//
|
// // movq mm1,mmword ptr[tmp]
|
// pmullw xmm1,xmm3; ×¢ÊÍ
|
// // movq mmword ptr[tmp],mm1
|
// // tmp = _mm_srli_pi16(tmp,7)
|
// // movq mm0,mmword ptr[tmp]
|
// psrlw xmm1,7;
|
// // movq mmwordptr[tmp],mm1;
|
// //tmp=_mm_packs_pu16(tmp,nNull);
|
// // movq mm0,mmword ptr [nNull]
|
// // movq mm1,mmword ptr [tmp]
|
// packuswb xmm1,xmm2;
|
// // movq mmword ptr [tmp],mm1;
|
// //c2->argb=_m_to_int(tmp)|0xff000000;
|
// // movq mm1,mmword ptr[tmp]
|
// movd dword ptr [eax+ecx*4],xmm1;
|
// //or edx,0ff000000h;
|
// //mov dword ptr[eax+ecx*4],edx;
|
// //mulps xmm3,xmm4;
|
//
|
// loop loop1
|
//
|
// //dec ebx;
|
// //jne loop1;
|
// }
|
// */
|
// //*///===============================================================
|
//
|
// }
|
// }
|
// // _mm_empty();
|
// }
|
// }
|
//
|
//
|
// bitmap1->UnlockBits(&bitmapdata0);
|
// double tick1=GetTickCountmS();
|
// CString s1;
|
// // s1.Format(_T("°×ƽºâÐÞÕýÍê³É ÓÃʱ %.2fmS\r\n"),tick1-tick0);
|
// // SysLog1(s1);
|
// return 1;
|
// }
|
int SecWhiteBalance::WBCorrectVC(Gdiplus::Bitmap * bitmap1,Gdiplus::Bitmap * bitmap2,float fRateV, float fRateR, float fRateG, float fRateB)
|
{
|
if (bitmap2==NULL||bitmap1==bitmap2)
|
{
|
return WBCorrect1VC(bitmap1,fRateV, fRateR, fRateG, fRateB);
|
}
|
else
|
{
|
return WBCorrect2VC(bitmap1,bitmap2,fRateV, fRateR, fRateG, fRateB);
|
}
|
return 0;
|
}
|
|
int SecWhiteBalance::WBCorrect1VC(Gdiplus::Bitmap * bitmap1,float fRateV, float fRateR, float fRateG, float fRateB)
|
{
|
if (this->wbcorrloaded==0) {return 0;}
|
double tick0=GetTickCountmS();
|
int i,j,k;
|
if (bitmap1==NULL)
|
{return 0;}
|
int w,h;
|
w=bitmap1->GetWidth();
|
h=bitmap1->GetHeight();
|
if (0==w||0==h)
|
{return 0;}
|
Gdiplus::BitmapData bitmapdata0;
|
UINT * pixels;
|
Gdiplus::Rect rect0(0,0,w,h);
|
// UINT * pixels2;
|
COLOR * c2;
|
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead|Gdiplus::ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata0);
|
if (GdipStatus!=Gdiplus::Ok)
|
{
|
CString Errs1;
|
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
// SysLog(Errs1);
|
return 0;
|
}
|
pixels=(UINT *)bitmapdata0.Scan0 ;
|
int s=bitmapdata0.Stride/4;
|
int yoff,ystep,xoff,xstep;
|
int offset;
|
float wbR,wbG,wbB;
|
short int R,G,B;
|
short int wbRcorr,wbGcorr,wbBcorr;
|
// if (0)
|
for (i=0;i<wbysecs;i++)
|
|
{ yoff=i*h/wbysecs;
|
ystep=(i+1)*h/wbysecs-yoff;
|
for (j=0;j<wbxsecs;j++)
|
{
|
xoff=j*w/wbxsecs;
|
xstep=(j+1)*w/wbxsecs-xoff;
|
wbR=wbsecR[i][j];
|
wbG=wbsecG[i][j];
|
wbB=wbsecB[i][j];
|
if (wbR<32) {wbR=32;}
|
if (wbG<32) {wbG=32;}
|
if (wbB<32) {wbB=32;}
|
if (TargetLight==0)
|
{
|
wbRcorr=int(128.0f*wbaveV*fRateV/wbR);
|
wbGcorr=int(128.0f*wbaveV*fRateV/wbG);
|
wbBcorr=int(128.0f*wbaveV*fRateV/wbB);
|
}
|
else if (TargetLightR*TargetLightG*TargetLightB==0)
|
{
|
wbRcorr=int(128.0f*TargetLight*fRateV/wbR);
|
wbGcorr=int(128.0f*TargetLight*fRateV/wbG);
|
wbBcorr=int(128.0f*TargetLight*fRateV/wbB);
|
}else
|
{
|
wbRcorr=int(128.0f*TargetLightR*fRateR/wbR);
|
wbGcorr=int(128.0f*TargetLightG*fRateG/wbG);
|
wbBcorr=int(128.0f*TargetLightB*fRateB/wbB);
|
}
|
//wbRcorr=0;
|
//wbGcorr=0;
|
//wbBcorr=0;
|
for (k=0;k<ystep;k++)
|
{
|
offset=(yoff+k)*s+xoff;
|
|
//continue;
|
c2=(COLOR *)(pixels+offset);
|
for (int l=0;l<xstep;l++)
|
{// pixels2=pixels+offset+l;
|
//continue;
|
R=c2->R*wbRcorr>>7;
|
c2->R=min(255,R);
|
G=c2->G*wbGcorr>>7;
|
c2->G=min(255,G);
|
B=c2->B*wbBcorr>>7;
|
c2->B =min(255,B);
|
// c2->R=0;
|
c2++;
|
}
|
}
|
}
|
}
|
bitmap1->UnlockBits(&bitmapdata0);
|
double tick1=GetTickCountmS();
|
return 1;
|
}
|
int SecWhiteBalance::WBCorrect2VC(Gdiplus::Bitmap * bitmap1,Gdiplus::Bitmap * bitmap2,float fRateV, float fRateR, float fRateG, float fRateB)
|
{
|
return 1;
|
}
|
|
int SecWhiteBalance::WBBayerCorrect(MyImage * Image1,MyImage * Image2,float fRateV, float fRateR, float fRateG, float fRateB)
|
{
|
return WBBayerCorrectVC(Image1, Image2, fRateV, fRateR, fRateG, fRateB);
|
}
|
int SecWhiteBalance::WBBayerCorrectVC(MyImage * Image1,MyImage * Image2,float fRateV, float fRateR, float fRateG, float fRateB)
|
{
|
if (Image2==NULL||Image1==Image2)
|
{
|
return WBBayerCorrect1VC(Image1->buffer,Image1->GetWidth(),Image1->GetHeight(),Image1->Stride, fRateV, fRateR, fRateG, fRateB);
|
}
|
else
|
{
|
return WBBayerCorrect2VC(Image1,Image2,fRateV, fRateR, fRateG, fRateB);
|
}
|
return 0;
|
}
|
int SecWhiteBalance::WBBayerCorrect1VC(void * buf1,int w,int h,int stride,float fRateV, float fRateR, float fRateG, float fRateB)
|
{
|
if (this->wbcorrloaded==0) {return 0;}
|
double tick0=GetTickCountmS();
|
int i,j,k;
|
if (buf1==NULL) {return 0;}
|
// int w,h;
|
// w=Image1->GetWidth();
|
// h=Image1->GetHeight();
|
if (0==w||0==h)
|
{return 0;}
|
// Gdiplus::BitmapData bitmapdata0;
|
unsigned char * pixels;
|
pixels=(unsigned char *)buf1 ;
|
int yoff,ystep,xoff,xstep;
|
int offset;
|
// float wbR,wbG,wbB,wbG2;
|
short int R,G,B,G2;
|
short int wbRcorr,wbGcorr,wbBcorr,wbG2corr;
|
|
for (i=0;i<wbysecs;i++)
|
{ yoff=i*(h/2)/wbysecs*2;
|
ystep=(i+1)*(h/2)/wbysecs*2-yoff;
|
for (j=0;j<wbxsecs;j++)
|
{
|
xoff=j*(w/2)/wbxsecs*2;
|
xstep=(j+1)*(w/2)/wbxsecs*2-xoff;
|
wbRcorr=wbsecRcorr[i][j]*fRateR;
|
wbGcorr=wbsecGcorr[i][j]*fRateG;
|
wbBcorr=wbsecBcorr[i][j]*fRateB;
|
wbG2corr=wbsecG2corr[i][j]*fRateG;
|
for (k=0;k<ystep;k+=2)
|
{
|
offset=(yoff+k)*stride+xoff;
|
unsigned char * c2;
|
//continue;
|
c2=(unsigned char *)(pixels+offset);
|
for (int l=0;l<xstep;l+=2)
|
{// pixels2=pixels+offset+l;
|
//continue;
|
|
G=(pixels[offset+l]*wbGcorr+64)/128;
|
pixels[offset+l]=min(255,G);;
|
R=(pixels[offset+l+1]*wbRcorr+64)/128;
|
pixels[offset+l+1]=min(255,R);
|
B=(pixels[offset+stride+l]*wbBcorr+64)/128;
|
pixels[offset+stride+l]=min(255,B);
|
G2=(pixels[offset+stride+l+1]*wbG2corr+64)/128;
|
pixels[offset+stride+l+1]=min(255,G2);
|
}
|
}
|
}
|
}
|
double tick1=GetTickCountmS();
|
return 0;
|
}
|
int SecWhiteBalance::WBBayerCorrect2VC(MyImage * Image1,MyImage * Image2,float fRateV, float fRateR, float fRateG, float fRateB)
|
{
|
if (this->wbcorrloaded==0) {return -1;}
|
double tick0=GetTickCountmS();
|
int i,j,k;
|
if (Image1==NULL) {return -1;}
|
if (!Image1->IsValid) {return -1;}
|
int w,h;
|
w=Image1->GetWidth();
|
h=Image1->GetHeight();
|
if (0==w||0==h)
|
{return 0;}
|
int w2,h2;
|
if (Image2==NULL) {return -1;}
|
if (!Image2->IsValid){Image2->AllocBuf(w,h,w,MyImage::MyPixelType_BayerGR8);}
|
w2=Image2->GetWidth();h2=Image2->GetHeight();
|
if (w!=w2||h!=h2) {Image2->AllocBuf(w,h,w,MyImage::MyPixelType_BayerGR8);}
|
unsigned char * pixels;
|
pixels=(unsigned char *)Image1->GetBuffer();
|
unsigned char * pixels2;
|
pixels2=(unsigned char *)Image2->GetBuffer();
|
int stride=Image1->GetStride();
|
int yoff,ystep,xoff,xstep;
|
int offset;
|
// float wbR,wbG,wbB,wbG2;
|
short int R,G,B,G2;
|
short int wbRcorr,wbGcorr,wbBcorr,wbG2corr;
|
|
for (i=0;i<wbysecs;i++)
|
{ yoff=i*(h/2)/wbysecs*2;
|
ystep=(i+1)*(h/2)/wbysecs*2-yoff;
|
for (j=0;j<wbxsecs;j++)
|
{
|
xoff=j*(w/2)/wbxsecs*2;
|
xstep=(j+1)*(w/2)/wbxsecs*2-xoff;
|
|
wbRcorr=wbsecRcorr[i][j]*fRateR;
|
wbGcorr=wbsecGcorr[i][j]*fRateG;
|
wbBcorr=wbsecBcorr[i][j]*fRateB;
|
wbG2corr=wbsecG2corr[i][j]*fRateG;
|
for (k=0;k<ystep;k+=2)
|
{
|
offset=(yoff+k)*stride+xoff;
|
unsigned char * c2;
|
//continue;
|
c2=(unsigned char *)(pixels+offset);
|
for (int l=0;l<xstep;l+=2)
|
{// pixels2=pixels+offset+l;
|
//continue;
|
G=(pixels[offset+l]*wbGcorr+64)/128;
|
pixels2[offset+l]=min(255,G);;
|
R=(pixels[offset+l+1]*wbRcorr+64)/128;
|
pixels2[offset+l+1]=min(255,R);
|
B=(pixels[offset+stride+l]*wbBcorr+64)/128;
|
pixels2[offset+stride+l]=min(255,B);
|
G2=(pixels[offset+stride+l+1]*wbG2corr+64)/128;
|
pixels2[offset+stride+l+1]=min(255,G2);
|
}
|
}
|
}
|
}
|
double tick1=GetTickCountmS();
|
return 0;
|
return -1;
|
}
|
|
int AveFilter(int inCount, int FilterSize, double inbuf[], double outbuf[])
|
{
|
return inCount;
|
}
|
int MidFilter(int inCount, int FilterSize, double inbuf[], double outbuf[])
|
{
|
return inCount;
|
}
|
int juanji(int incount,int corecount,double inbuf[], double outbuf[],double corebuf[])
|
{
|
int i,j;
|
int k1=(corecount)/2;
|
int k2=(corecount+1)/2;
|
int l;
|
double sum1;
|
for (i=0;i<k1;i++) //Æðʼ±ßÔµ´¦Àí
|
{
|
sum1=0;
|
for (j=0;j<corecount;j++)
|
{
|
l=i-k1+j;
|
if (l<0) {l=0;}
|
sum1+=inbuf[l]*corebuf[j];
|
}
|
outbuf[i]=sum1;
|
}
|
for (i=k1;i<incount-k1;i++) //Õý³£Öµ´¦Àí
|
{
|
sum1=0;
|
for (j=0;j<corecount;j++)
|
{
|
l=i-k1+j;
|
sum1+=inbuf[l]*corebuf[j];
|
}
|
outbuf[i]=sum1;
|
// outbuf[i]=inbuf[i];
|
}
|
for (i=incount-k1;i<incount;i++) //½áÊø±ßÔµ´¦Àí
|
{
|
sum1=0;
|
for (j=0;j<corecount;j++)
|
{
|
l=i-k1+j;
|
if (l>incount-1) {l=incount-1;}
|
sum1+=inbuf[l]*corebuf[j];
|
}
|
outbuf[i]=sum1;
|
}
|
return i;
|
}
|
|
int juanjiV(int incount,int corecount,int stride, int x, double inbuf[], double outbuf[],double corebuf[])
|
{
|
int i,j;
|
int k1=(corecount)/2;
|
int l;
|
double sum1;
|
for (i=0;i<incount;i++)
|
{
|
sum1=0;
|
for (j=0;j<corecount;j++)
|
{
|
l=i-k1+j;
|
if (l<0)
|
{
|
l=0;
|
}
|
if (l>incount-1)
|
{
|
l=incount-1;
|
}
|
sum1+=inbuf[l*stride + x]*corebuf[j];
|
}
|
outbuf[i*stride + x]=sum1;
|
}
|
|
return i;
|
}
|
|
int juanji2D(double inbuf[], int sizex, int sizey, int stride, double outbuf[], double corebuf[], int coresizex, int coresizey, int corestrie)
|
{
|
int halfcorex=coresizex/2;
|
int halfcorey=coresizey/2;
|
|
//for (int i = 0; i < sizey; i++)
|
//{
|
// int l0 = i*stride;
|
// int startcory = (i - halfcorey < 0) ? halfcorey - i : 0;
|
// int endcory = (i + coresizey - 1 >= sizey) ? coresizey - (i + coresizey - sizey) : coresizey;
|
// for (int j = 0; j < sizex; j++)
|
// {
|
// int startcorx = (j - halfcorex < 0) ? halfcorex - j : 0;;
|
// int endcorx = (j + coresizex - 1 >= sizex) ? coresizex - (j + coresizex - sizex) : coresizex;
|
// int l1 = l0 + j;
|
// outbuf[l1] = 0;
|
// for (int k = startcory; k < endcory; k++)
|
// {
|
// int l2 = l1 + (k - halfcorey)*stride;
|
|
// for (int l = startcorx; l < endcorx; l++)
|
// {
|
// outbuf[l1] += inbuf[l2 + (l - halfcorex)] * corebuf[k*corestrie + l];
|
// }
|
// }
|
|
// }
|
//}
|
|
for (int i = 0; i < halfcorey; i++)
|
{
|
int l0 = i*stride;
|
for (int j = 0; j < halfcorex; j++) outbuf[l0 + j] = 0;
|
for (int j = sizex-halfcorex; j < sizex; j++) outbuf[l0 + j] = 0;
|
}
|
|
for (int i = sizey-halfcorey; i < sizey; i++)
|
{
|
int l0 = i*stride;
|
for (int j = 0; j < halfcorex; j++) outbuf[l0 + j] = 0;
|
for (int j = sizex - halfcorex; j < sizex; j++) outbuf[l0 + j] = 0;
|
}
|
|
for (int i=halfcorey;i<sizey-halfcorey;i++) //Õý³£ÔËËã
|
{
|
int l0=i*stride;
|
for (int j=halfcorex;j<sizex-halfcorex;j++)
|
{
|
int l1=l0+j;
|
outbuf[l1]=0;
|
for (int k=0;k<coresizey;k++)
|
{
|
int l2=l1+(k-halfcorey)*stride;
|
for (int l=0;l<coresizex;l++)
|
{
|
outbuf[l1]+=inbuf[l2+(l-halfcorex)]*corebuf[k*corestrie+l];
|
}
|
}
|
}
|
}
|
|
return sizex*sizey;
|
}
|
// template <typename T>
|
// int juanji2D3x3(T inbuf[], int sizex, int sizey, int stride, T outbuf[], T corebuf[3][3])
|
// {
|
//
|
// for (int i=1;i<sizey-1;i++) //Õý³£ÔËËã//ÄÚ²¿ÇøÓò
|
// {
|
// int l0=(i-1)*stride;
|
// int l1=(i)*stride;
|
// int l2=(i+1)*stride;
|
// for (int j=1;j<sizex-1;j++)
|
// {
|
// T a1,a2,a3;
|
// a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
|
// a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
// a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
// outbuf[l1+j]=a1+a2+a3;
|
// }
|
// }
|
// for (int i=0;i<1;i++) //´¦Àí±ßÔµ£¬ÉϱßÔµ,²»°üÀ¨×óÉϽǺÍÓÒÉϽǣ»
|
// {
|
// int l1=(i)*stride;
|
// int l2=(i+1)*stride;
|
// for (int j=1;j<sizex-1;j++)
|
// {
|
// outbuf[l1+j]=outbuf[l2+j];
|
// }
|
// }
|
// for (int i=sizey-1;i<sizey;i++) //ϱßÔµ£¬²»°üÀ¨×óϽǺÍÓÒϽÇ
|
// {
|
// int l0=(i-1)*stride;
|
// int l1=(i)*stride;
|
//
|
// for (int j=1;j<sizex-1;j++)
|
// {
|
// outbuf[l1+j]=outbuf[l0+j];
|
// }
|
// }
|
// for (int i=1;i<sizey-1;i++) //×ó±ßÔµ£¬²»°üÀ¨×óÉϽǺÍ×óϽÇ
|
// {
|
// int l=(i)*stride;
|
// for (int j=0;j<1;j++)
|
// {
|
// outbuf[l+j]=outbuf[l+j+1];
|
// }
|
// }
|
// for (int i=1;i<sizey-1;i++) //ÓÒ±ßÔµ£¬²»°üÀ¨ÓÒÉϽǺÍÓÒϽÇ
|
// {
|
// int l=(i)*stride;
|
// for (int j=sizex-1;j<sizex;j++)
|
// {
|
// outbuf[l+j]=outbuf[l+j-1];
|
// }
|
// }
|
// //Ëĸö½Ç
|
// for (int i=0;i<1;i++)
|
// {
|
// int l1=(i)*stride;
|
// int l2=(i+1)*stride;
|
// for (int j=0;j<1;j++)
|
// {
|
// T a1,a2,a3;
|
// outbuf[l1+j]=(outbuf[l2+j]+outbuf[l1+j+1])/2;
|
// }
|
// for (int j=sizex-1;j<sizex;j++)
|
// {
|
// outbuf[l1+j]=(outbuf[l2+j]+outbuf[l1+j-1])/2;
|
// }
|
// }
|
// for (int i=sizey-1;i<sizey;i++)
|
// {
|
// int l0=(i-1)*stride;
|
// int l1=(i)*stride;
|
// for (int j=0;j<1;j++)
|
// {
|
//
|
// outbuf[l1+j]=(outbuf[l0+j]+outbuf[l1+j+1])/2;
|
// }
|
// for (int j=sizex-1;j<sizex;j++)
|
// {
|
// outbuf[l1+j]=(outbuf[l0+j]+outbuf[l1+j-1])/2;
|
// }
|
// }
|
//
|
// return sizex*sizey;
|
// }
|
template <typename T>
|
int juanji2D3x3(T inbuf[], int sizex, int sizey, int stride, T outbuf[], T corebuf[3][3])
|
{
|
|
for (int i=1;i<sizey-1;i++) //Õý³£ÔËËã//ÄÚ²¿ÇøÓò
|
{
|
int l0=(i-1)*stride;
|
int l1=(i)*stride;
|
int l2=(i+1)*stride;
|
for (int j=1;j<sizex-1;j++)
|
{
|
T a1,a2,a3;
|
// __m256 m1,m2,m3;
|
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m2=_mm256_loadu_ps(&corebuf);
|
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
|
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
}
|
for (int i=0;i<1;i++) //´¦Àí±ßÔµ£¬ÉϱßÔµ,²»°üÀ¨×óÉϽǺÍÓÒÉϽǣ»
|
{
|
// int l0=(i)*stride;
|
int l1=(i)*stride;
|
int l2=(i+1)*stride;
|
for (int j=1;j<sizex-1;j++)
|
{
|
T a1,a2,a3;
|
// __m256 m1,m2,m3;
|
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m2=_mm256_loadu_ps(&corebuf);
|
a1=(inbuf[l1+j-1]*2-inbuf[l2+j-1])*corebuf[0][0]+(inbuf[l1+j]*2-inbuf[l2+j])*corebuf[0][1]+(inbuf[l1+j+1]*2-inbuf[l2+j+1])*corebuf[0][2];
|
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
}
|
for (int i=sizey-1;i<sizey;i++) //ϱßÔµ£¬²»°üÀ¨×óϽǺÍÓÒϽÇ
|
{
|
int l0=(i-1)*stride;
|
int l1=(i)*stride;
|
// int l2=(i)*stride;
|
|
for (int j=1;j<sizex-1;j++)
|
{
|
T a1,a2,a3;
|
// __m256 m1,m2,m3;
|
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m2=_mm256_loadu_ps(&corebuf);
|
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
|
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
a3=(inbuf[l1+j-1]*2-inbuf[l0+j-1])*corebuf[2][0]+(inbuf[l1+j]*2-inbuf[l0+j])*corebuf[2][1]+(inbuf[l1+j+1]*2-inbuf[l0+j+1])*corebuf[2][2];
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
}
|
for (int i=1;i<sizey-1;i++) //×ó±ßÔµ£¬²»°üÀ¨×óÉϽǺÍ×óϽÇ
|
{
|
int l0=(i-1)*stride;
|
int l1=(i)*stride;
|
int l2=(i+1)*stride;
|
for (int j=0;j<1;j++)
|
{
|
T a1,a2,a3;
|
// __m256 m1,m2,m3;
|
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m2=_mm256_loadu_ps(&corebuf);
|
a1=(inbuf[l0+j]*2-inbuf[l0+j+1])*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
|
a2=(inbuf[l1+j]*2-inbuf[l1+j+1])*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
a3=(inbuf[l2+j]*2-inbuf[l2+j+1])*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
}
|
for (int i=1;i<sizey-1;i++) //ÓÒ±ßÔµ£¬²»°üÀ¨ÓÒÉϽǺÍÓÒϽÇ
|
{
|
int l0=(i-1)*stride;
|
int l1=(i)*stride;
|
int l2=(i+1)*stride;
|
for (int j=sizex-1;j<sizex;j++)
|
{
|
T a1,a2,a3;
|
// __m256 m1,m2,m3;
|
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m2=_mm256_loadu_ps(&corebuf);
|
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+(inbuf[l0+j]*2-inbuf[l0+j-1])*corebuf[0][2];
|
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+(inbuf[l1+j]*2-inbuf[l1+j-1])*corebuf[1][2];
|
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+(inbuf[l2+j]*2-inbuf[l2+j-1])*corebuf[2][2];
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
}
|
//Ëĸö½Ç
|
for (int i=0;i<1;i++)
|
{
|
int l0=(i)*stride;
|
int l1=(i)*stride;
|
int l2=(i+1)*stride;
|
for (int j=0;j<1;j++)
|
{
|
T a1,a2,a3;
|
// __m256 m1,m2,m3;
|
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m2=_mm256_loadu_ps(&corebuf);
|
a1=inbuf[l0+j]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
|
a2=inbuf[l1+j]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
|
a3=inbuf[l2+j]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
for (int j=sizex-1;j<sizex;j++)
|
{
|
T a1,a2,a3;
|
// __m256 m1,m2,m3;
|
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m2=_mm256_loadu_ps(&corebuf);
|
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
|
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
|
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
}
|
for (int i=sizey-1;i<sizey;i++)
|
{
|
int l0=(i-1)*stride;
|
int l1=(i)*stride;
|
int l2=(i)*stride;
|
for (int j=0;j<1;j++)
|
{
|
T a1,a2,a3;
|
// __m256 m1,m2,m3;
|
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m2=_mm256_loadu_ps(&corebuf);
|
a1=inbuf[l0+j]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
|
a2=inbuf[l1+j]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
|
a3=inbuf[l2+j]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
for (int j=sizex-1;j<sizex;j++)
|
{
|
T a1,a2,a3;
|
// __m256 m1,m2,m3;
|
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m2=_mm256_loadu_ps(&corebuf);
|
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
|
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
|
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
}
|
|
return sizex*sizey;
|
}
|
template<> int juanji2D3x3(float inbuf[], int sizex, int sizey, int stride, float outbuf[], float corebuf[3][3])
|
{
|
__m256 km1,km2,km3;
|
km1=_mm256_loadu_ps(corebuf[0]);
|
km2=_mm256_loadu_ps(corebuf[1]);
|
km3=_mm256_loadu_ps(corebuf[2]);
|
km1=_mm256_shuffle_ps(km2,km3,0x4e);
|
// _mm256_rsqrt_ps()
|
for (int i=1;i<sizey-1;i++) //Õý³£ÔËËã
|
{
|
int l0=(i-1)*stride;
|
int l1=(i)*stride;
|
int l2=(i+1)*stride;
|
for (int j=1;j<sizex-1;j++)
|
{
|
float a1,a2,a3;
|
// __m256 m1,m2,m3,m4,m5,m6;
|
// m1=_mm256_loadu_ps(&inbuf[l0+j-1]);
|
// m2=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
// m4=_mm256_mul_ps(m1,km1);
|
// m3=_mm256_loadu_ps(&inbuf[l2+j-1]);
|
// m5=_mm256_mul_ps(m2,km2);
|
// m6=_mm256_mul_ps(m3,km3);
|
// m1=_mm256_add_ps(m4,m5);
|
// m1=_mm256_add_ps(m1,m6);
|
// a1=m1.m256_f32[0];a2=m1.m256_f32[1];a3=m1.m256_f32[2];
|
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
|
|
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
|
outbuf[l1+j]=a1+a2+a3;
|
}
|
}
|
for (int i=0;i<1;i++) //´¦Àí±ßÔµ£¬ËùÓеıßÔµµÈÓÚ0£»
|
{
|
int l1=(i)*stride;
|
for (int j=0;j<sizex;j++)
|
{
|
outbuf[l1+j]=0;
|
}
|
}
|
for (int i=sizey-1;i<sizey;i++)
|
{
|
int l1=(i)*stride;
|
for (int j=0;j<sizex;j++)
|
{
|
outbuf[l1+j]=0;
|
}
|
}
|
for (int i=0;i<sizey;i++)
|
{
|
int l1=(i)*stride;
|
for (int j=0;j<1;j++)
|
{
|
outbuf[l1+j]=0;
|
}
|
}
|
for (int i=0;i<sizey;i++)
|
{
|
int l1=(i)*stride;
|
for (int j=sizex-1;j<sizex;j++)
|
{
|
outbuf[l1+j]=0;
|
}
|
}
|
return sizex*sizey;
|
}
|
void dummy1(void)
|
{
|
double a[1];
|
double b[3][3];
|
juanji2D3x3(a,1,1,1,a,b);
|
float c[1];
|
float d[3][3];
|
juanji2D3x3(c,1,1,1,c,d);
|
}
|
|
int DCT(double pt[], double dpt[],int size,int start,int end)
|
{
|
if (size&1) {size=size-1;}
|
dpt[0]=0;
|
for (int j=0;j<size;j++)
|
{
|
dpt[0]+=pt[j];
|
}
|
dpt[0]/=sqrt(double(size));
|
for (int i=start;i<=end;i++)
|
{
|
dpt[i]=0;
|
for (int j=0;j<size;j++)
|
{
|
dpt[i]+=pt[j]*cos((2*j+1)*i*3.1415926535897932384626433/(2*size));
|
}
|
dpt[i]/=sqrt(double(size)/2);
|
}
|
return 1;
|
}
|
|
int DCT(float pt[], float dpt[],int size,int start,int end)
|
{
|
if (size&1) {size=size-1;}
|
dpt[0]=0;
|
for (int j=0;j<size;j++)
|
{
|
dpt[0]+=pt[j];
|
}
|
dpt[0]/=sqrt(float(size));
|
for (int i=start;i<end;i++)
|
{
|
dpt[i]=0;
|
for (int j=0;j<size;j++)
|
{
|
dpt[i]+=pt[j]*cos((2*j+1)*i*3.1415926535897932384626433f/2/size);
|
}
|
dpt[i]/=sqrt(float(size)/2);
|
}
|
return 1;
|
}
|
|
int FDCT(double pt[], double dpt[],int size,int start,int end)
|
{
|
if (size&1) {size=size-1;}
|
double * costab=new double[4*size+4];
|
for (int i=0;i<=size;i++)
|
{//¼ÆËãÓàÏÒ±í
|
double result1=cos(i*3.1415926535897932384626433/2/size);
|
costab[i]=result1;
|
costab[2*size-i]=-result1;
|
costab[2*size+i]=-result1;
|
costab[4*size-i]=result1;
|
}
|
|
dpt[0]=0;
|
for (int j=0;j<size;j++)
|
{
|
dpt[0]+=pt[j];
|
}
|
dpt[0]/=sqrt(double(size));
|
for (int i=start;i<=end;i++)
|
{
|
dpt[i]=0;
|
for (int j=0;j<size;j++)
|
{
|
dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)];
|
}
|
dpt[i]/=sqrt(double(size)/2);
|
}
|
delete [] costab;
|
return 1;
|
}
|
|
int FDCT(float pt[], float dpt[],int size,int start,int end)
|
{
|
if (size&1) {size=size-1;}
|
dpt[0]=0;
|
float * costab=new float[4*size+4];
|
for (int i=0;i<size;i++)
|
{//¼ÆËãÓàÏÒ±í
|
float result1=cosf(i*3.1415926535897932384626433f/2/size);
|
costab[i]=result1;
|
costab[2*size-i]=-result1;
|
costab[2*size+i]=-result1;
|
costab[4*size-i]=result1;
|
}
|
|
for (int j=0;j<size;j++)
|
{
|
dpt[0]+=pt[j];
|
}
|
dpt[0]/=sqrt(float(size));
|
for (int i=start;i<end;i++)
|
{
|
dpt[i]=0;
|
for (int j=0;j<size;j++)
|
{
|
dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)]; //cos((2*j+1)*i*3.1415926f/2/size);
|
}
|
dpt[i]/=sqrt(float(size)/2);
|
}
|
delete [] costab;
|
return 1;
|
}
|
|
int FFDCT(double pt[], double dpt[],int size,int start,int end)
|
{
|
if (size&1) {size=size-1;}
|
double * costab=new double[4*size+4];
|
for (int i=0;i<size;i++)
|
{//¼ÆËãÓàÏÒ±í
|
double result1=cos(i*3.1415926535897932384626433/2/size);
|
costab[i]=result1;
|
costab[2*size-i]=-result1;
|
costab[2*size+i]=-result1;
|
costab[4*size-i]=result1;
|
}
|
|
dpt[0]=0;
|
for (int j=0;j<size;j++)
|
{
|
dpt[0]+=pt[j];
|
}
|
dpt[0]/=sqrt(double(size));
|
for (int i=start;i<=end;i++)
|
{
|
dpt[i]=0;
|
int j;
|
for (j=0;j<size-7;j+=8)
|
{
|
double temp[8];
|
temp[0]=pt[j]*costab[(2*j+1)*i%(4*size)];
|
temp[1]=pt[j+1]*costab[(2*j+3)*i%(4*size)];
|
temp[2]=pt[j+2]*costab[(2*j+5)*i%(4*size)];
|
temp[3]=pt[j+3]*costab[(2*j+7)*i%(4*size)];
|
temp[4]=pt[j+4]*costab[(2*j+9)*i%(4*size)];
|
temp[5]=pt[j+5]*costab[(2*j+11)*i%(4*size)];
|
temp[6]=pt[j+6]*costab[(2*j+13)*i%(4*size)];
|
temp[7]=pt[j+7]*costab[(2*j+15)*i%(4*size)];
|
|
dpt[i]+=temp[0]+temp[1]+temp[2]+temp[3]+temp[4]+temp[5]+temp[6]+temp[7];
|
}
|
for (;j<size;j++)
|
{
|
dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)]; //cos((2*j+1)*i*3.1415926f/2/size);
|
}
|
dpt[i]/=sqrt(double(size)/2);
|
}
|
delete [] costab;
|
return 1;
|
}
|
|
int FFDCT(float pt[], float dpt[],int size,int start,int end)
|
{
|
if (size&1) {size=size-1;}
|
float * costab=new float[4*size];
|
for (int i=0;i<size;i++)
|
{//¼ÆËãÓàÏÒ±í
|
float result1=cosf(i*3.1415926535897932384626433f/2/size);
|
costab[i]=result1;
|
costab[2*size-1-i]=-result1;
|
costab[2*size+i]=-result1;
|
costab[4*size-1-i]=result1;
|
}
|
|
dpt[0]=0;
|
for (int j=0;j<size;j++)
|
{
|
dpt[0]+=pt[j];
|
}
|
dpt[0]/=sqrt(float(size));
|
for (int i=start;i<=end;i++)
|
{
|
dpt[i]=0;
|
int j;
|
for (j=0;j<size-7;j+=8)
|
{
|
_CRT_ALIGN(32) float temp[8];
|
// _CRT_ALIGN(32) float results[8];
|
temp[0]=pt[j]*costab[(2*j+1)*i%(4*size)];
|
temp[1]=pt[j+1]*costab[(2*j+3)*i%(4*size)];
|
temp[2]=pt[j+2]*costab[(2*j+5)*i%(4*size)];
|
temp[3]=pt[j+3]*costab[(2*j+7)*i%(4*size)];
|
temp[4]=pt[j+4]*costab[(2*j+9)*i%(4*size)];
|
temp[5]=pt[j+5]*costab[(2*j+11)*i%(4*size)];
|
temp[6]=pt[j+6]*costab[(2*j+13)*i%(4*size)];
|
temp[7]=pt[j+7]*costab[(2*j+15)*i%(4*size)];
|
|
/*
|
results[0]=costab[(2*j+1)*i%(2*size)];
|
results[1]=costab[(2*j+3)*i%(2*size)];
|
results[2]=costab[(2*j+5)*i%(2*size)];
|
results[3]=costab[(2*j+6)*i%(2*size)];
|
results[4]=costab[(2*j+9)*i%(2*size)];
|
results[5]=costab[(2*j+11)*i%(2*size)];
|
results[6]=costab[(2*j+13)*i%(2*size)];
|
results[7]=costab[(2*j+15)*i%(2*size)];
|
temp[0]=pt[j]*results[0];
|
temp[1]=pt[j+1]*results[1];
|
temp[2]=pt[j+2]*results[2];
|
temp[3]=pt[j+3]*results[3];
|
temp[4]=pt[j+4]*results[4];
|
temp[5]=pt[j+5]*results[5];
|
temp[6]=pt[j+6]*results[6];
|
temp[7]=pt[j+7]*results[7];
|
*/
|
// __m256 a,b,c;
|
// a=_mm256_loadu_ps(&pt[j]);
|
// b=_mm256_loadu_ps(results);
|
// c=_mm256_mul_ps(a,b);
|
// _mm256_storeu_ps(temp,c);
|
dpt[i]+=temp[0]+temp[1]+temp[2]+temp[3]+temp[4]+temp[5]+temp[6]+temp[7];
|
// dpt[i]+=((temp[0]+temp[1])+(temp[2]+temp[3]))+((temp[4]+temp[5])+(temp[6]+temp[7]));
|
}
|
for (;j<size;j++)
|
{
|
dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)]; //cos((2*j+1)*i*3.1415926f/2/size);
|
}
|
dpt[i]/=sqrt(float(size)/2);
|
}
|
delete [] costab;
|
return 1;
|
}
|
|
/*
|
int juanji2D3x3(float inbuf[], int sizex, int sizey, int stride, float outbuf[], float corebuf[3][3])
|
{
|
|
for (int i=1;i<sizey-1;i++) //Õý³£ÔËËã
|
{
|
int l0=(i-1)*stride;
|
int l1=(i)*stride;
|
int l2=(i+1)*stride;
|
for (int j=1;j<sizex-1;j++)
|
{
|
outbuf[l1+j]=
|
inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2]+
|
inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2]+
|
inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
}
|
}
|
for (int i=0;i<1;i++) //´¦Àí±ßÔµ£¬ËùÓеıßÔµµÈÓÚ0£»
|
{
|
int l1=(i)*stride;
|
for (int j=0;j<sizex;j++)
|
{
|
outbuf[l1+j]=0;
|
}
|
}
|
for (int i=sizey-1;i<sizey;i++)
|
{
|
int l1=(i)*stride;
|
for (int j=0;j<sizex;j++)
|
{
|
outbuf[l1+j]=0;
|
}
|
}
|
for (int i=0;i<sizey;i++)
|
{
|
int l1=(i)*stride;
|
for (int j=0;j<1;j++)
|
{
|
outbuf[l1+j]=0;
|
}
|
}
|
for (int i=0;i<sizey;i++)
|
{
|
int l1=(i)*stride;
|
for (int j=sizex-1;j<sizex;j++)
|
{
|
outbuf[l1+j]=0;
|
}
|
}
|
return sizex*sizey;
|
}
|
*/
|
int nihe(CPoint pt5[100],int pt5total,int pt5valid[100])
|
{
|
int i,j,k;//,l;
|
int startpt,endpt;
|
double angle1,angle2;
|
double distance,intercept;
|
double maxintercept=3;
|
double totalintercept;
|
int validpts;
|
int maxstartpt,maxendpt;
|
int maxvalidpts;
|
double minintercept;
|
maxvalidpts=0;
|
int ptvalid[100];
|
maxstartpt=0;
|
maxendpt=1;
|
|
for (i=0;i<pt5total;i++)
|
{
|
ptvalid[i]=0;
|
}
|
|
for (i=0;i<pt5total-1;i++)
|
{
|
startpt=i;
|
ptvalid[i]=1;
|
for (j=i+1;j<pt5total;j++)
|
{
|
validpts=0;
|
endpt=j;
|
angle1=atan(((double)pt5[i].x-pt5[j].x)/((double)pt5[i].y-pt5[j].y));
|
totalintercept=0;
|
ptvalid[j]=1;
|
for (k=0;k<pt5total;k++)
|
{
|
if (k==i) {continue;}
|
if (k==j) {continue;}
|
angle2=atan(((double)pt5[i].x-pt5[k].x)/((double)pt5[i].y-pt5[k].y));
|
distance=sqrt((double)(pt5[i].x-pt5[k].x)*(pt5[i].x-pt5[k].x)+(pt5[i].y-pt5[k].y)*(pt5[i].y-pt5[k].y));
|
intercept=distance*sin(abs(angle2-angle1));
|
if (intercept<maxintercept)
|
{
|
ptvalid[k]=1;
|
validpts++;
|
totalintercept+=intercept;
|
}
|
else
|
{
|
ptvalid[k]=0;
|
}
|
}
|
if ((validpts>maxvalidpts)||(validpts==maxvalidpts&&totalintercept<minintercept))
|
{
|
maxvalidpts=validpts;
|
maxstartpt=startpt;
|
maxendpt=endpt;
|
minintercept=totalintercept;
|
for (k=0;k<pt5total;k++)
|
{
|
pt5valid[k]=ptvalid[k];
|
}
|
|
}
|
ptvalid[j]=0;
|
}
|
ptvalid[i]=0;
|
}
|
return MAKELONG(maxstartpt,maxendpt);
|
}
|
|
UINT __cdecl memcpyThread(LPVOID pParam)
|
{
|
MemcpyThreadDataStruct * p1=(MemcpyThreadDataStruct *)pParam;
|
void * dest2,*src2;
|
unsigned long size_t2;
|
dest2=p1->dest;
|
src2=p1->src;
|
size_t2=p1->size;
|
X_aligned_memcpy_sse2(dest2, src2, size_t2);
|
p1->done=1;
|
return 1000;
|
}
|
|
void fastmemcpy(void* dest, const void* src, const unsigned long size_t)
|
{
|
void * dest2,* src2;
|
unsigned long size_t2;
|
src2=(void *)src;
|
dest2=dest;
|
size_t2=size_t;
|
if (((UINT)dest)&0xf)
|
{
|
UINT delta;
|
|
dest2=(void *)((((UINT)dest)+15)&0xfffffff0);
|
delta=(UINT)dest2-(UINT)dest;
|
size_t2-=delta;
|
src=(void *)((UINT(src))+delta);
|
}
|
|
X_aligned_memcpy_sse2(dest2, src2, size_t2);
|
}
|
void fastmemcpyMT(void* dest, const void* src, const unsigned long size_t)
|
{
|
MemcpyThreadDataStruct threaddata[2];
|
threaddata[0].src=(void *)src;
|
threaddata[0].dest=dest;
|
threaddata[0].size=size_t/2;
|
threaddata[0].done=0;
|
|
threaddata[1].src=(unsigned char *)src+size_t/2;
|
threaddata[1].dest=(unsigned char *)dest+size_t/2;
|
threaddata[1].size=size_t/2;
|
threaddata[1].done=0;
|
AfxBeginThread(memcpyThread,LPVOID(&threaddata[0]));
|
AfxBeginThread(memcpyThread,LPVOID(&threaddata[1]));
|
while(1)
|
{
|
if (threaddata[0].done&&threaddata[1].done) {break;}
|
}
|
|
|
}
|
|
int GetLineSegmentPart(double startx, double starty, double endx, double endy, double numerator, double denominator, double & x1, double & y1)
|
{
|
|
x1=(startx*(denominator-numerator)+endx*numerator)/denominator;
|
y1=(starty*(denominator-numerator)+endy*numerator)/denominator;
|
return 1;
|
}
|
|
double LineSegmentDirection(PointD pt1,PointD pt2,PointD pt3)
|
{
|
PointD d1,d2;
|
d1=pt3-pt1;d2=pt2-pt1;
|
return d1.x*d2.y-d1.y*d2.x;
|
|
}
|
int IsOnLineSegment(MyLineSegment linesegment1,PointD pt1)
|
{
|
double x_min,x_max,y_min,y_max;
|
if (linesegment1.start.x<linesegment1.end.x)
|
{
|
x_min=linesegment1.start.x;
|
x_max=linesegment1.end.x;
|
}
|
else
|
{
|
x_min=linesegment1.end.x;
|
x_max=linesegment1.start.x;
|
}
|
if (linesegment1.start.y<linesegment1.end.y)
|
{
|
y_min=linesegment1.start.y;
|
y_max=linesegment1.end.y;
|
}
|
else
|
{
|
y_min=linesegment1.end.y;
|
y_max=linesegment1.start.y;
|
}
|
if (pt1.x<x_min||pt1.x>x_max||pt1.y<y_min||pt1.y>y_max)
|
return false;
|
else return true;
|
}
|
|
int IsLineSegmentCross(MyLineSegment linesegment1, MyLineSegment linesegment2)
|
{
|
PointD pt1,pt2,pt3,pt4;
|
pt1=linesegment1.start;pt2=linesegment1.end;
|
pt3=linesegment2.start;pt4=linesegment2.end;
|
double d1,d2,d3,d4;
|
d1=LineSegmentDirection(pt3,pt4,pt1);
|
d2=LineSegmentDirection(pt3,pt4,pt2);
|
d3=LineSegmentDirection(pt1,pt2,pt3);
|
d4=LineSegmentDirection(pt1,pt2,pt4);
|
if (d1*d2<0&&d3*d4<0)
|
return true;
|
else if (d1==0&&IsOnLineSegment(linesegment2,pt1)) return true;
|
else if (d2==0&&IsOnLineSegment(linesegment2,pt2)) return true;
|
else if (d3==0&&IsOnLineSegment(linesegment1,pt3)) return true;
|
else if (d4==0&&IsOnLineSegment(linesegment1,pt4)) return true;
|
else return false;
|
}
|
/*
|
int IsLineSegmentCross(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
|
{
|
PointD pt1,pt2,pt3,pt4;
|
pt1=PointD(x1,y1);pt2=PointD(x2,y2);
|
pt3=PointD(x3,y3);pt4=PointD(x4,y4);
|
double d1,d2,d3,d4;
|
d1=LineSegmentDirection(pt3,pt4,pt1);
|
d2=LineSegmentDirection(pt3,pt4,pt2);
|
d3=LineSegmentDirection(pt1,pt2,pt3);
|
d4=LineSegmentDirection(pt1,pt2,pt4);
|
if (d1*d2<0&&d3*d4<0)
|
return true;
|
else if (d1==0&&IsOnLineSegment(linesegment2,pt1)) return true;
|
else if (d2==0&&IsOnLineSegment(linesegment2,pt2)) return true;
|
else if (d3==0&&IsOnLineSegment(linesegment1,pt3)) return true;
|
else if (d4==0&&IsOnLineSegment(linesegment1,pt4)) return true;
|
else return false;
|
return false;
|
}
|
*/
|
int CannyËã·¨()
|
{
|
return 0;
|
};
|
|
int Hough(MyImage& img1,stHoughResult res[],int MaxFound, double Threshold,int starta,int enda)
|
{
|
const int hough_space=256;
|
int width=img1.Width;
|
int height=img1.Height;
|
int stride=img1.Stride;
|
|
int centerX=width/2;
|
int centerY=height/2;
|
double hough_interval=3.1415926535897932384626433/(double)hough_space;
|
|
int maxL=max(width,height);
|
int max_length=(int)(1.41421356237*maxL);
|
int hough_strides=(max_length+3)&0xfffffffc;
|
unsigned char *pixels=(unsigned char *)img1.GetBuffer();
|
/*
|
//½¨Á¢ÌØÕ÷µãµÄ¼¯ºÏ
|
int TotalPixel=0;
|
Point ptx[9999];
|
unsigned char score1[9999];
|
for (int i=0;i<height;i++)
|
{
|
for (int j=0;j<width;j++)
|
{
|
if (pixels[i*stride+j]==0) continue;
|
if (TotalPixel<9999-1)
|
{
|
ptx[TotalPixel].X=j;
|
ptx[TotalPixel].Y=i;
|
score1[TotalPixel]=pixels[i*stride+j];
|
TotalPixel++;
|
}
|
}
|
}
|
*/
|
//½¨Á¢²ÎÊý¿Õ¼ä
|
int *hough_2d=new int[hough_space*hough_strides];
|
//²ÎÊý¿Õ¼äÇåÁã
|
for (int i=0;i<hough_space;i++)
|
{
|
for (int j=0;j<max_length;j++)
|
{
|
hough_2d[i*hough_strides+j]=0;
|
}
|
}
|
int minb=999,maxb=0;
|
//ÏñËØÓ³Éäµ½²ÎÊý¿Õ¼ä
|
for (int i=0;i<height;i++)
|
{
|
int n=i*stride;
|
for (int j=0;j<width;j++)
|
{
|
unsigned char pixel=pixels[n+j];
|
if (pixel==0) continue;
|
int maxk=0;
|
for (int cell=starta;cell<enda;cell++)
|
{
|
maxk=(int)((j-centerX)*cos(cell*hough_interval-Pi/4)+(i-centerY)*sin(cell*hough_interval-Pi/4)+max_length/2);
|
//maxk+=max_length/2;
|
if (maxk>maxb) {maxb=maxk;}
|
if (maxk<minb) {minb=maxk;}
|
if (maxk<0||(maxk>=max_length))
|
{
|
continue;
|
}
|
hough_2d[cell*hough_strides+maxk]+=pixel;
|
}
|
|
}
|
}
|
int max_hough=0;
|
int max_x=0,max_y=0;
|
//²ÎÊý¿Õ¼äÕÒ×î´óÖµ
|
for (int i=starta;i<enda/*hough_space*/;i++)
|
{
|
for (int j=1;j<max_length-1;j++)
|
{
|
int thissum=0;
|
for (int k=-1;k<2;k++)
|
{
|
for (int l=-1;l<2;l++)
|
{
|
thissum+=hough_2d[i*hough_strides+j];
|
}
|
}
|
if (thissum>max_hough)
|
{
|
max_hough=thissum;
|
max_x=j;max_y=i;
|
}
|
}
|
}
|
//ÕÒ¼«Öµ
|
int totalfound=0;
|
res[totalfound].Pt=PointD(max_y,max_x-max_length/2);
|
res[totalfound].Score=max_hough;
|
totalfound++;
|
for (int i=starta+1;i<enda-1 /*hough_space-1*/;i++)
|
{
|
for (int j=1;j<max_length-1;j++)
|
{
|
int nofound=0;
|
int thissum=0;
|
for (int k=-1;k<2;k++)
|
{
|
for (int l=-1;l<2;l++)
|
{
|
thissum+=hough_2d[i*hough_strides+j];
|
}
|
}
|
if (thissum<Threshold) continue;
|
for (int k=-1;k<2;k++)
|
{
|
for (int l=-1;l<2;l++)
|
{
|
if (k==0&&l==0) continue;
|
if (hough_2d[i*hough_strides+j]<hough_2d[(i+k)*hough_strides+(j+l)])
|
{
|
nofound=1;
|
break;
|
}
|
}
|
if (nofound) break;
|
}
|
if (nofound) continue; //found but not peak
|
if (totalfound<MaxFound-1)
|
{
|
res[totalfound].Pt=PointD(i,j-max_length/2);
|
res[totalfound].Score=thissum;
|
totalfound++;
|
if (totalfound>=MaxFound) break;
|
}
|
}
|
}
|
/*
|
//ת»»µ½Í¼ÏñÏÔʾ
|
char factor=max_hough/127;
|
if (factor<1) {factor=1;}
|
if (max_hough<1) {max_hough=1;}
|
unsigned char *hough_2d2=new unsigned char[hough_space*hough_strides];
|
int kk;
|
for (int i=0;i<hough_space;i++)
|
{
|
for (int j=0;j<max_length;j++)
|
{
|
kk=hough_2d[i*hough_strides+j]*255*8/max_hough;
|
hough_2d2[i*hough_strides+j]=kk;
|
}
|
}
|
//±£´æͼÏñ
|
// SaveBufferToBmpFile(hough_2d2,max_length,hough_space,hough_strides,_T("d:\\1\\Hough001.bmp"));
|
delete [] hough_2d2;
|
// vector <int> a;
|
//*/
|
delete [] hough_2d;
|
return totalfound;
|
return 0;
|
}
|
|
int NewHough(MyImage& img1,stHoughResult res[],int MaxFound, double Threshold,int starta,int enda)
|
{
|
const int hough_space=256;
|
int width=img1.Width;
|
int height=img1.Height;
|
int stride=img1.Stride;
|
|
int centerX=width/2;
|
int centerY=height/2;
|
double hough_interval=3.1415926535897932384626433/(double)hough_space;
|
|
int maxL=max(width,height);
|
int max_length=(int)(1.41421356237*maxL);
|
int hough_strides=(max_length+3)&0xfffffffc;
|
unsigned char *pixels=(unsigned char *)img1.GetBuffer();
|
|
//½¨Á¢ÌØÕ÷µãµÄ¼¯ºÏ
|
int TotalPixel=0;
|
Gdiplus::Point ptx[9999];
|
unsigned char score1[9999];
|
unsigned char used[9999];
|
unsigned char used2[9999];
|
for (int i=0;i<height;i++)
|
{
|
for (int j=0;j<width;j++)
|
{
|
if (pixels[i*stride+j]==0) continue;
|
if (TotalPixel<9999-1)
|
{
|
ptx[TotalPixel].X=j;
|
ptx[TotalPixel].Y=i;
|
score1[TotalPixel]=pixels[i*stride+j];
|
used[TotalPixel]=0;
|
used2[TotalPixel]=0;
|
TotalPixel++;
|
}
|
}
|
}
|
//±ä»Ã£»
|
int minL=10;
|
int totalfound=0;
|
double ee=0.5;
|
int first,second;
|
for (first=0;first<TotalPixel-30;first++)
|
{
|
if (used[first]) continue;
|
for (second=first+10;second<TotalPixel;second++)
|
{
|
if (used[second]) continue;
|
if (used2[second]) continue;
|
int counterk=0;
|
int x1,y1,x2,y2;
|
x1=ptx[first].X;y1=ptx[first].Y;
|
x2=ptx[second].X;y2=ptx[second].Y;
|
//ÅжϾàÀ룬Èç¹û¾àÀëСÓÚminL£¬·ÅÆú
|
int dx,dy,dl;
|
dx=x2-x1;dy=y2-y1;
|
dl=(dx)*dx+dy*dy;
|
if (dl<minL*minL) continue;
|
double theta,ro;
|
if (y2==y1) {theta=Pi/2;}
|
else {theta=atan((double)x2-x1/y2-y1);}
|
ro=((x1-centerX)*cos(theta)+(y1-centerY)*sin(theta))+max_length/2;
|
for (int k=first+1;k<TotalPixel;k++)
|
{
|
if (used[k]) continue;
|
int x3,y3;
|
double ro3;
|
x3=ptx[k].X;y3=ptx[k].Y;
|
ro3=((x3-centerX)*cos(theta)+(y3-centerY)*sin(theta)+max_length/2);
|
if (fabs(ro-ro3)<ee)
|
{
|
used2[k]=1;
|
counterk++;
|
}
|
}
|
if (counterk>Threshold)
|
{
|
for (int l=0;l<TotalPixel;l++)
|
{
|
if (used2[l]) used[l]=used2[l];
|
}
|
if (totalfound<1000-1)
|
{
|
res[totalfound].Pt=PointD(theta,ro-max_length/2);
|
res[totalfound].Score=counterk;
|
totalfound++;
|
if (totalfound>=MaxFound) break;
|
}
|
break;
|
}
|
}
|
}
|
return totalfound;
|
return 0;
|
}
|
int TransRGBToBayerGR(Gdiplus::Bitmap * bitmap1,CString sFilePathname)
|
{
|
if (bitmap1==NULL) {return 0;}
|
int w,h;
|
w=bitmap1->GetWidth();
|
h=bitmap1->GetHeight();
|
if (0==w||0==h) {return 0;}
|
|
Gdiplus::BitmapData bitmapdata0;
|
UINT * pixels;
|
Gdiplus::Rect rect0(0,0,w,h);
|
|
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapdata0);
|
if (GdipStatus!=Gdiplus::Ok)
|
{
|
CString Errs1;
|
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
return 0;
|
}
|
pixels=(UINT *)bitmapdata0.Scan0 ;
|
int stride=bitmapdata0.Stride/4;
|
int stride2=(stride+63)&(-64);
|
unsigned char * buf1=new unsigned char [h*stride2];
|
//#pragma omp parallel for
|
for (int i=0;i<h;i+=2)
|
{
|
COLOR c1;
|
for (int j=0;j<w;j+=2)
|
{
|
c1.argb=pixels[i*stride+j];
|
buf1[i*stride2+j]=c1.G;
|
c1.argb=pixels[i*stride+j+1];
|
buf1[i*stride2+j+1]=c1.R;
|
}
|
for (int j=0;j<w;j+=2)
|
{
|
c1.argb=pixels[(i+1)*stride+j];
|
buf1[(i+1)*stride2+j]=c1.B;
|
c1.argb=pixels[(i+1)*stride+j+1];
|
buf1[(i+1)*stride2+j+1]=c1.G;
|
}
|
}
|
bitmap1->UnlockBits(&bitmapdata0);
|
SaveBufferToBmpFile(buf1,w,h,stride2,sFilePathname);
|
delete []buf1;
|
return true;
|
}
|
int TransRGBToBayerGR2(Gdiplus::Bitmap * bitmap1,CString sFilePathname)
|
{
|
if (bitmap1==NULL) {return 0;}
|
int w,h;
|
w=bitmap1->GetWidth();
|
h=bitmap1->GetHeight();
|
if (0==w||0==h) {return 0;}
|
|
Gdiplus::BitmapData bitmapdata0;
|
UINT * pixels;
|
Gdiplus::Rect rect0(0,0,w,h);
|
|
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapdata0);
|
if (GdipStatus!=Gdiplus::Ok)
|
{
|
CString Errs1;
|
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
return 0;
|
}
|
pixels=(UINT *)bitmapdata0.Scan0 ;
|
int stride=bitmapdata0.Stride/4;
|
unsigned char * buf1=new unsigned char [h*stride];
|
#pragma omp parallel for
|
for (int i=0;i<h;i+=2)
|
{
|
COLOR c1;
|
for (int j=0;j<w;j+=2)
|
{
|
c1.argb=pixels[i*stride+j];
|
buf1[(i/2)*stride+j/2]=c1.G;
|
c1.argb=pixels[i*stride+j+1];
|
buf1[(i/2)*stride+j/2+w/2]=c1.R;
|
}
|
for (int j=0;j<w;j+=2)
|
{
|
c1.argb=pixels[(i+1)*stride+j];
|
buf1[(i/2+h/2)*stride+j/2]=c1.B;
|
c1.argb=pixels[(i+1)*stride+j+1];
|
buf1[(i/2+h/2)*stride+j/2+w/2]=c1.G;
|
}
|
}
|
bitmap1->UnlockBits(&bitmapdata0);
|
SaveBufferToBmpFile(buf1,w,h,stride,sFilePathname);
|
delete [] buf1;
|
return true;
|
}
|
|
double RefCompare(double * buf1, int count1, double * buf2, int count2 ,int mode)
|
{
|
double refcount=0;
|
int count=min(count1,count2);
|
double a,b,c=0;
|
for (int i=0;i<count;i++)
|
{
|
a=buf1[i];
|
b=buf2[i];
|
c+=(a-b)*(a-b);
|
}
|
refcount=sqrt(c);
|
|
return refcount;
|
}
|
/*
|
#include "opencv2/opencv.hpp"
|
#ifdef _DEBUG
|
#pragma comment(lib,"opencv_core341d.lib")
|
#pragma comment(lib,"opencv_imgproc341d.lib")
|
#pragma comment(lib,"opencv_imgcodecs341d.lib")
|
#pragma comment(lib,"opencv_highgui341d.lib")
|
#else
|
#pragma comment(lib,"opencv_core341.lib")
|
#pragma comment(lib,"opencv_imgproc341.lib")
|
#pragma comment(lib,"opencv_imgcodecs341.lib")
|
#pragma comment(lib,"opencv_highgui341.lib")
|
#endif
|
*/
|
#ifdef _WIN64
|
|
#include "E:\OpenCV3\opencv\build\include\opencv2\opencv.hpp"
|
#ifdef _DEBUG
|
#pragma comment(lib,"opencv_world310d.lib")
|
#else
|
#pragma comment(lib,"opencv_world310.lib")
|
#endif
|
int fdf1(double * pData, int width, int height, DftFilterPos filterPos[], int filterPosCount, int showstatus)
|
{
|
CString s1;
|
double time1,time2;
|
time1 = GetTickCountmS();
|
|
cv::Mat input(height,width,CV_64FC1,pData);
|
|
int w=cv::getOptimalDFTSize(input.cols);
|
int h=cv::getOptimalDFTSize(input.rows);//»ñÈ¡×î¼Ñ³ß´ç£¬¿ìËÙ¸µÁ¢Ò¶±ä»»ÒªÇó³ß´çΪ2µÄn´Î·½
|
cv::Mat padded;
|
cv::copyMakeBorder(input,padded,0,h-input.rows,0,w-input.cols,cv::BORDER_CONSTANT,cv::Scalar::all(0));//Ìî³äͼÏñ±£´æµ½paddedÖÐ
|
|
cv::Mat plane[]={cv::Mat_<float>(padded),cv::Mat::zeros(padded.size(),CV_32F)};//´´½¨Í¨µÀ
|
cv::Mat complexIm1;
|
cv::Mat complexIm2;
|
cv::Mat complexIm3;
|
|
time2=GetTickCountmS();
|
s1.Format(_T("fdf init %.3fmS\r\n"),time2-time1);
|
TRACE(s1);
|
|
if (showstatus)
|
{
|
cv::Mat T;
|
plane[0].copyTo(T);
|
cv::normalize(T,T,255,0,CV_MINMAX);
|
cv::imwrite("D:\\1\\fdf_padded.bmp",cv::Mat_<uchar>(T));
|
}
|
|
time1 = GetTickCountmS();
|
//*******************************dft************************************
|
cv::merge(plane,2,complexIm1);//ºÏ²¢Í¨µÀ
|
cv::dft(complexIm1,complexIm2);//½øÐиµÁ¢Ò¶±ä»»£¬½á¹û±£´æÔÚ×ÔÉí
|
cv::split(complexIm2,plane);//·ÖÀëͨµÀ
|
|
time2=GetTickCountmS();
|
s1.Format(_T("fdf dft %.3fmS\r\n"),time2-time1);
|
TRACE(s1);
|
|
if (1)
|
{
|
time1 = GetTickCountmS();
|
//*******************************shift************************************
|
{
|
int cx=plane[0].cols/2;
|
int cy=plane[0].rows/2;
|
cv::Mat temp;
|
cv::Mat part1(plane[0],cv::Rect(0,0,cx,cy));
|
cv::Mat part2(plane[0],cv::Rect(cx,0,cx,cy));
|
cv::Mat part3(plane[0],cv::Rect(0,cy,cx,cy));
|
cv::Mat part4(plane[0],cv::Rect(cx,cy,cx,cy));
|
|
part1.copyTo(temp);
|
part4.copyTo(part1);
|
temp.copyTo(part4);
|
|
part2.copyTo(temp);
|
part3.copyTo(part2);
|
temp.copyTo(part3);
|
}
|
{
|
int cx=plane[0].cols/2;
|
int cy=plane[0].rows/2;
|
cv::Mat temp;
|
|
cv::Mat part1(plane[1],cv::Rect(0,0,cx,cy));
|
cv::Mat part2(plane[1],cv::Rect(cx,0,cx,cy));
|
cv::Mat part3(plane[1],cv::Rect(0,cy,cx,cy));
|
cv::Mat part4(plane[1],cv::Rect(cx,cy,cx,cy));
|
|
part1.copyTo(temp);
|
part4.copyTo(part1);
|
temp.copyTo(part4);
|
|
part2.copyTo(temp);
|
part3.copyTo(part2);
|
temp.copyTo(part3);
|
}
|
time2=GetTickCountmS();
|
s1.Format(_T("fdf shift %.3fmS\r\n"),time2-time1);
|
TRACE(s1);
|
}
|
|
if (showstatus)
|
{
|
cv::Mat T;
|
cv::magnitude(plane[0],plane[1],T);
|
T+=cv::Scalar::all(1);
|
cv::log(T,T);
|
cv::normalize(T,T,255,0,CV_MINMAX);
|
cv::imwrite("D:\\1\\fdf_dft.bmp",cv::Mat_<uchar>(T));
|
}
|
|
if (1)
|
{
|
time1 = GetTickCountmS();
|
//*******************************filter************************************
|
for (int k=0; k<filterPosCount; k++)
|
{
|
int startx = w/2 - filterPos[k].x - filterPos[k].w/2;
|
int endx = w/2 - filterPos[k].x + filterPos[k].w/2;
|
int starty = h/2 - filterPos[k].y - filterPos[k].h/2;
|
int endy = h/2 - filterPos[k].y + filterPos[k].h/2;
|
|
if (startx<0) startx = 0;
|
if (starty<0) starty = 0;
|
if (endx>w) endx = w;
|
if (endy>h) endy = h;
|
|
for (int i=starty; i<endy; ++i)
|
{
|
float*p0=plane[0].ptr<float>(i);
|
for (int j=startx; j<endx; j++)
|
{
|
p0[j]=0;
|
}
|
|
float*p1=plane[1].ptr<float>(i);
|
for (int j=startx; j<endx; j++)
|
{
|
p1[j]=0;
|
}
|
}
|
}
|
|
time2=GetTickCountmS();
|
s1.Format(_T("fdf filter %.3fmS\r\n"),time2-time1);
|
TRACE(s1);
|
}
|
|
if (showstatus)
|
{
|
cv::Mat T;
|
cv::magnitude(plane[0],plane[1],T);
|
T+=cv::Scalar::all(1);
|
cv::log(T,T);
|
cv::normalize(T,T,255,0,CV_MINMAX);
|
cv::imwrite("D:\\1\\fdf_dft_filtered.bmp",cv::Mat_<uchar>(T));
|
}
|
|
if (1)
|
{
|
time1 = GetTickCountmS();
|
//*******************************shift************************************
|
{
|
int cx=plane[0].cols/2;
|
int cy=plane[0].rows/2;
|
cv::Mat temp;
|
cv::Mat part1(plane[0],cv::Rect(0,0,cx,cy));
|
cv::Mat part2(plane[0],cv::Rect(cx,0,cx,cy));
|
cv::Mat part3(plane[0],cv::Rect(0,cy,cx,cy));
|
cv::Mat part4(plane[0],cv::Rect(cx,cy,cx,cy));
|
|
part1.copyTo(temp);
|
part4.copyTo(part1);
|
temp.copyTo(part4);
|
|
part2.copyTo(temp);
|
part3.copyTo(part2);
|
temp.copyTo(part3);
|
}
|
{
|
int cx=plane[0].cols/2;
|
int cy=plane[0].rows/2;
|
cv::Mat temp;
|
|
cv::Mat part1(plane[1],cv::Rect(0,0,cx,cy));
|
cv::Mat part2(plane[1],cv::Rect(cx,0,cx,cy));
|
cv::Mat part3(plane[1],cv::Rect(0,cy,cx,cy));
|
cv::Mat part4(plane[1],cv::Rect(cx,cy,cx,cy));
|
|
part1.copyTo(temp);
|
part4.copyTo(part1);
|
temp.copyTo(part4);
|
|
part2.copyTo(temp);
|
part3.copyTo(part2);
|
temp.copyTo(part3);
|
}
|
|
time2=GetTickCountmS();
|
s1.Format(_T("fdf ishift %.3fmS\r\n"),time2-time1);
|
TRACE(s1);
|
}
|
|
time1 = GetTickCountmS();
|
//*****************************idft**************************************
|
cv::merge(plane,2,complexIm2);
|
cv::idft(complexIm2,complexIm3);//¸µÁ¢Ò¶Äæ±ä»»
|
cv::split(complexIm3,plane);//½á¹ûÒ²ÊǸ´Êý
|
|
time2=GetTickCountmS();
|
s1.Format(_T("fdf idft %.3fmS\r\n"),time2-time1);
|
TRACE(s1);
|
|
time1 = GetTickCountmS();
|
cv::Mat output;
|
plane[0].copyTo(output);
|
cv::normalize(output,output,255,0,CV_MINMAX);
|
for (int i=0; i<height; ++i)
|
{
|
float*p0=output.ptr<float>(i);
|
for (int j=0; j<width; ++j)
|
{
|
pData[i*width+j] = p0[j];
|
}
|
}
|
time2=GetTickCountmS();
|
s1.Format(_T("fdf output %.3fmS\r\n"),time2-time1);
|
TRACE(s1);
|
|
if (showstatus)
|
{
|
cv::Mat T;
|
plane[0].copyTo(T);
|
cv::normalize(T,T,255,0,CV_MINMAX);
|
cv::imwrite("D:\\1\\fdf_idft.bmp",cv::Mat_<uchar>(T));
|
}
|
|
return 0;
|
}
|
#endif /* _WIN64 */
|
|