提交 | 用户 | age
|
4b03ae
|
1 |
#include "stdafx.h"
|
Q |
2 |
#include "ImageFunc.h"
|
|
3 |
#include <WinGDI.h>
|
|
4 |
#include <omp.h>
|
|
5 |
#include <math.h>
|
|
6 |
#include <intrin.h>
|
|
7 |
#include "../Functions.hpp"
|
|
8 |
#include "../MHashINI/MHash.hpp"
|
|
9 |
#define Pi 3.1415926535897932384626433
|
|
10 |
|
|
11 |
using namespace Gdiplus;
|
|
12 |
#pragma comment(lib,"gdiplus.lib")
|
|
13 |
|
|
14 |
int MyImage::AllocBuf(int width,int height,int stride,int PixelFormat1)
|
|
15 |
{
|
|
16 |
if (ShowCache != NULL) { ::delete ShowCache; ShowCache = NULL; }
|
|
17 |
//stride ,以64字节对齐?
|
|
18 |
if (stride==0) {stride=(width+Stride_Align-1)&(-Stride_Align);}
|
|
19 |
if (buffer0!=NULL)
|
|
20 |
{
|
|
21 |
if (width==this->Width&&height==this->Height&&stride==this->Stride)
|
|
22 |
{
|
|
23 |
this->PixelFormat=PixelFormat1;
|
|
24 |
m_thumbImg.IsValid=0;
|
|
25 |
return true;
|
|
26 |
}
|
|
27 |
delete[] buffer0;
|
|
28 |
delete[] buffer2;
|
|
29 |
delete[] buffer3;
|
|
30 |
|
|
31 |
}
|
|
32 |
buffer0=new unsigned char[stride*height+Stride_Align];
|
|
33 |
buffer=(void *)(((INT_PTR)buffer0+Stride_Align-1)&(INT_PTR)(-Stride_Align));
|
|
34 |
this->Width=width;
|
|
35 |
this->Height=height;
|
|
36 |
this->Stride=stride;
|
|
37 |
if (PixelFormat1!=0) this->PixelFormat=PixelFormat1;
|
|
38 |
else {this->PixelFormat=MyPixelType_Mono8;}
|
|
39 |
if (PixelFormat1 == MyPixelType_RGB8planar)
|
|
40 |
{
|
|
41 |
buffer2 = new unsigned char[stride*height + Stride_Align];
|
|
42 |
buffer3 = new unsigned char[stride*height + Stride_Align];
|
|
43 |
}
|
|
44 |
IsValid=true;
|
|
45 |
|
|
46 |
return true;
|
|
47 |
}
|
|
48 |
|
|
49 |
int MyImage::CopyFromGdipBitMap(Gdiplus::Bitmap * bitmap1)
|
|
50 |
{
|
|
51 |
if (bitmap1==NULL) {return -1;}
|
|
52 |
int w,h;
|
|
53 |
w=bitmap1->GetWidth();
|
|
54 |
h=bitmap1->GetHeight();
|
|
55 |
Rect rect1;
|
|
56 |
rect1.X=0;rect1.Y=0;rect1.Width=w;rect1.Height=h;
|
|
57 |
BitmapData bitmapData1;
|
|
58 |
|
|
59 |
Gdiplus::PixelFormat pixelformat = bitmap1->GetPixelFormat();
|
|
60 |
if (pixelformat==PixelFormat8bppIndexed)
|
|
61 |
{
|
|
62 |
bitmap1->LockBits(&rect1,ImageLockModeRead,PixelFormat8bppIndexed,&bitmapData1);
|
|
63 |
int stride1=bitmapData1.Stride;
|
|
64 |
unsigned char * buf1=(unsigned char *)bitmapData1.Scan0;
|
|
65 |
int r=CopyFromBuf(buf1,w,h,stride1,MyPixelType_Mono8);
|
|
66 |
}else
|
|
67 |
{
|
|
68 |
bitmap1->LockBits(&rect1,ImageLockModeRead,PixelFormat32bppRGB,&bitmapData1);
|
|
69 |
int stride1=bitmapData1.Stride;
|
|
70 |
DWORD * buf1=(DWORD *)bitmapData1.Scan0;
|
|
71 |
// this->AllocBuf(w,h);
|
|
72 |
// int stride2=this->Stride;
|
|
73 |
// unsigned char * pixels=(unsigned char *)buffer;
|
|
74 |
// for (int i=0;i<h;i++)
|
|
75 |
// {
|
|
76 |
// int l1=i*stride1/4;
|
|
77 |
// int l=i*stride2;
|
|
78 |
// for (int j=0;j<w;j++)
|
|
79 |
// {
|
|
80 |
// COLOR c1;
|
|
81 |
// c1.argb=buf1[l1+j];
|
|
82 |
// pixels[l+j]=RGBtoVI(c1.R,c1.G,c1.B);
|
|
83 |
// }
|
|
84 |
// }
|
|
85 |
int r=CopyFromBuf(buf1,w,h,stride1,MyPixelType_ARGB32);
|
|
86 |
}
|
|
87 |
bitmap1->UnlockBits(&bitmapData1);
|
|
88 |
return 1;
|
|
89 |
}
|
|
90 |
|
|
91 |
int MyImage::LoadFromBitmapFile(CString sFilePathName)
|
|
92 |
{
|
|
93 |
Bitmap bitmap1(sFilePathName);
|
|
94 |
this->CopyFromGdipBitMap(&bitmap1);
|
|
95 |
int j = sFilePathName.MakeUpper().Find(_T(".RAW"));
|
|
96 |
if ( j!= -1)
|
|
97 |
{
|
|
98 |
int k = this->PixelFormat;
|
|
99 |
if ( k == MyPixelType_Mono8)
|
|
100 |
{
|
|
101 |
this->PixelFormat = MyPixelType_BayerGR8;
|
|
102 |
}
|
|
103 |
|
|
104 |
}
|
|
105 |
return 0;
|
|
106 |
}
|
|
107 |
|
|
108 |
int MyImage::SaveToFile(CString sFilePathName)
|
|
109 |
{
|
|
110 |
if (this->PixelFormat == MyPixelType_RGB8planar)
|
|
111 |
{
|
|
112 |
return 0;
|
|
113 |
|
|
114 |
}if (this->PixelFormat == MyPixelType_ARGB32)
|
|
115 |
{
|
|
116 |
Bitmap * bitmap1=NULL;
|
|
117 |
ConvertTypeToGdipBitmap32(&bitmap1);
|
|
118 |
int r=SaveGdiPImageAsFile(bitmap1, sFilePathName);
|
|
119 |
return r;
|
|
120 |
}
|
|
121 |
else
|
|
122 |
{
|
|
123 |
int r = SaveBufferToBmpFile(buffer, Width, Height, Stride, sFilePathName, 0, 0);
|
|
124 |
return r;
|
|
125 |
}
|
|
126 |
}
|
|
127 |
|
|
128 |
int MyImage::LoadRegionFromFile(CString sFilePathName)
|
|
129 |
{
|
|
130 |
myregions.clear();
|
|
131 |
MHash RegionCfg;
|
|
132 |
RegionCfg.LoadFromFile(sFilePathName);
|
|
133 |
|
|
134 |
int k = _tstoi(RegionCfg["Regions"]["TotalRegion"]);
|
|
135 |
for (int i = 0; i < k; i++)
|
|
136 |
{
|
|
137 |
MyRegion thisRegion;
|
|
138 |
|
|
139 |
CString RegionNo;
|
|
140 |
RegionNo.Format(_T("Region%d"), i + 1);
|
|
141 |
thisRegion.IsValid = _tstoi(RegionCfg[RegionNo]["IsValid"]);
|
|
142 |
thisRegion.RegionStr = RegionCfg[RegionNo]["Str"];
|
|
143 |
thisRegion.RegionColor = _tstoi(RegionCfg[RegionNo]["Color"]);
|
|
144 |
int PtCount=_tstoi(RegionCfg[RegionNo]["PtCount"]);
|
|
145 |
|
|
146 |
CString ResultStr[10];
|
|
147 |
for (int j = 0; j < PtCount; j++)
|
|
148 |
{
|
|
149 |
CString PtNo;
|
|
150 |
PtNo.Format(_T("Pt%d"), j + 1);
|
|
151 |
CString thisptstr = RegionCfg[RegionNo][PtNo];
|
|
152 |
Split(thisptstr, _T(","), ResultStr);
|
|
153 |
MyPoint thispt;
|
|
154 |
thispt.X = _tstoi(ResultStr[0]);
|
|
155 |
thispt.Y = _tstoi(ResultStr[1]);
|
|
156 |
thisRegion.pts.push_back(thispt);
|
|
157 |
}
|
|
158 |
myregions.push_back(thisRegion);
|
|
159 |
}
|
|
160 |
return 0;
|
|
161 |
}
|
|
162 |
int MyImage::SaveRegionToFile(CString sFilePathName)
|
|
163 |
{
|
|
164 |
CString s1;
|
|
165 |
MHash RegionCfg;
|
|
166 |
int k = myregions.size();
|
|
167 |
s1.Format(_T("%d"), k);
|
|
168 |
RegionCfg["Regions"]["TotalRegion"]=s1;
|
|
169 |
for (int i = 0; i < k; i++)
|
|
170 |
{
|
|
171 |
MyRegion thisRegion;
|
|
172 |
thisRegion = myregions.at(i);
|
|
173 |
|
|
174 |
CString RegionNo;
|
|
175 |
RegionNo.Format(_T("Region%d"), i + 1);
|
|
176 |
s1.Format(_T("%d"), thisRegion.IsValid);
|
|
177 |
RegionCfg[RegionNo]["IsValid"]=s1;
|
|
178 |
RegionCfg[RegionNo]["Str"]=thisRegion.RegionStr;
|
|
179 |
s1.Format(_T("%d"), thisRegion.RegionColor);
|
|
180 |
RegionCfg[RegionNo]["Color"]=s1;
|
|
181 |
|
|
182 |
int PtCount = thisRegion.pts.size();
|
|
183 |
s1.Format(_T("%d"), PtCount);
|
|
184 |
RegionCfg[RegionNo]["PtCount"]=s1;
|
|
185 |
|
|
186 |
for (int j = 0; j < PtCount; j++)
|
|
187 |
{
|
|
188 |
CString PtNo;
|
|
189 |
MyPoint thispt;
|
|
190 |
PtNo.Format(_T("Pt%d"), j + 1);
|
|
191 |
thispt = thisRegion.pts.at(j);
|
|
192 |
s1.Format(_T("%d,%d"), thispt.X, thispt.Y);
|
|
193 |
RegionCfg[RegionNo][PtNo]=s1;
|
|
194 |
}
|
|
195 |
}
|
|
196 |
RegionCfg.SaveToFile(sFilePathName);
|
|
197 |
return 0;
|
|
198 |
}
|
|
199 |
|
|
200 |
int MyImage::CopyFromBuf(void * buf,int w,int h,int stride,int pixelformat)
|
|
201 |
{
|
|
202 |
if (stride==0)
|
|
203 |
{
|
|
204 |
stride=(w+Stride_Align-1)&(-Stride_Align);
|
|
205 |
}
|
|
206 |
|
|
207 |
SN=0;
|
|
208 |
|
|
209 |
if (pixelformat==MyPixelType_BayerGB8)
|
|
210 |
{
|
|
211 |
int bpp = stride/w;
|
|
212 |
int newstride = stride - 2*bpp;
|
|
213 |
AllocBuf(w-2,h-2,newstride,pixelformat);
|
|
214 |
for (int i=0; i<h-2; ++i)
|
|
215 |
{
|
|
216 |
memcpy((char*)buffer+i*newstride,(char*)buf+(i+1)*stride+bpp,newstride);
|
|
217 |
}
|
|
218 |
this->PixelFormat=MyPixelType_BayerGR8;
|
|
219 |
}else
|
|
220 |
{
|
|
221 |
AllocBuf(w,h,stride,pixelformat);
|
|
222 |
memcpy(buffer,buf,h*stride);
|
|
223 |
}
|
|
224 |
// this->PixelFormat=pixelformat;
|
|
225 |
return true;
|
|
226 |
};
|
|
227 |
|
|
228 |
int MyImage::CopyFromBufR90(void * buf,int w,int h,int stride,int pixelformat)
|
|
229 |
{
|
|
230 |
AllocBuf(h,w,h,pixelformat);
|
|
231 |
for (int i=0;i<w;i++)
|
|
232 |
{
|
|
233 |
for (int j=0;j<h;j++)
|
|
234 |
{
|
|
235 |
((UCHAR *)buffer)[i*Stride+j]=((UCHAR *)buf)[(j)*stride+(w-i-1)];
|
|
236 |
}
|
|
237 |
}
|
|
238 |
// memcpy(buffer,buf,h*stride);
|
|
239 |
this->PixelFormat=MyPixelType_Mono8;
|
|
240 |
return true;
|
|
241 |
};
|
|
242 |
|
|
243 |
int MyImage::Meg3ImgIntoRGB8planar(MyImage & img1, MyImage &img2, MyImage & img3)
|
|
244 |
{
|
|
245 |
int nwidth, nheight, nstride;
|
|
246 |
nwidth = img1.Width;
|
|
247 |
nheight = img1.Height;
|
|
248 |
nstride = img1.Stride ;
|
|
249 |
this->PixelFormat = MyPixelType_RGB8planar;
|
|
250 |
AllocBuf(nwidth, nheight, nstride, MyPixelType_RGB8planar );
|
|
251 |
|
|
252 |
memcpy(buffer, img1.buffer, nwidth*nheight);
|
|
253 |
memcpy(buffer2, img2.buffer, nwidth*nheight);
|
|
254 |
memcpy(buffer3, img3.buffer, nwidth*nheight);
|
|
255 |
return 0;
|
|
256 |
}
|
|
257 |
|
|
258 |
int MyImage::Meg3ImgIntoRGB(MyImage & img1, MyImage &img2, MyImage & img3)
|
|
259 |
{
|
|
260 |
int nwidth, nheight, nstride;
|
|
261 |
nwidth = img1.Width;
|
|
262 |
nheight = img1.Height;
|
|
263 |
nstride = img1.Stride * 4;
|
|
264 |
this->PixelFormat = MyPixelType_ARGB32;
|
|
265 |
AllocBuf(nwidth, nheight, nstride, MyPixelType_ARGB32);
|
|
266 |
|
|
267 |
for (int i = 0; i < nheight; i++)
|
|
268 |
{
|
|
269 |
unsigned char * line1 = (unsigned char *)img3.buffer + i*img1.Stride;
|
|
270 |
unsigned char * line2 = (unsigned char *)img2.buffer + i*img2.Stride;
|
|
271 |
unsigned char * line3 = (unsigned char *)img1.buffer + i*img3.Stride;
|
|
272 |
unsigned char * line5 = (unsigned char *)buffer + i*nstride;
|
|
273 |
for (int j = 0; j < nwidth; j+=4)
|
|
274 |
{
|
|
275 |
line5[j*4 ] = line1[j];
|
|
276 |
line5[j*4+1] = line2[j];
|
|
277 |
line5[j*4+2] = line3[j];
|
|
278 |
|
|
279 |
line5[j * 4 + 4] = line1[j+1];
|
|
280 |
line5[j * 4 + 5] = line2[j+1];
|
|
281 |
line5[j * 4 + 6] = line3[j+1];
|
|
282 |
|
|
283 |
line5[j * 4 + 8] = line1[j+2];
|
|
284 |
line5[j * 4 + 9] = line2[j+2];
|
|
285 |
line5[j * 4 + 10] = line3[j+2];
|
|
286 |
|
|
287 |
line5[j * 4 + 12] = line1[j+3];
|
|
288 |
line5[j * 4 + 13] = line2[j+3];
|
|
289 |
line5[j * 4 + 14] = line3[j+3];
|
|
290 |
/*
|
|
291 |
c1.R = line1[j+4];
|
|
292 |
c1.G = line2[j + 4];
|
|
293 |
c1.B = line3[j + 4];
|
|
294 |
line5[j + 4] = c1.argb;
|
|
295 |
c2.R = line1[j + 5];
|
|
296 |
c2.G = line2[j + 5];
|
|
297 |
c2.B = line3[j + 5];
|
|
298 |
line5[j + 5] = c2.argb;
|
|
299 |
c3.R = line1[j + 6];
|
|
300 |
c3.G = line2[j + 6];
|
|
301 |
c3.B = line3[j + 6];
|
|
302 |
line5[j + 6] = c3.argb;
|
|
303 |
c4.R = line1[j + 7];
|
|
304 |
c4.G = line2[j + 7];
|
|
305 |
c4.B = line3[j + 7];
|
|
306 |
line5[j + 7] = c4.argb;
|
|
307 |
//*/
|
|
308 |
}
|
|
309 |
}
|
|
310 |
return 0;
|
|
311 |
}
|
|
312 |
|
|
313 |
int MyImage::CreateThumbImg(int Width, int Height,float startX, float startY , float swidth, float sheight )
|
|
314 |
{
|
|
315 |
if (!IsValid) return -1;
|
|
316 |
int nThumbWidth, nThumbHeight;
|
|
317 |
float nSrcStartX, nSrcStartY, nSrcWidth, nSrcHeight;
|
|
318 |
if (Width == 0 || Height == 0)
|
|
319 |
{
|
|
320 |
nThumbWidth = 1280;
|
|
321 |
nThumbHeight = 960;
|
|
322 |
nSrcStartX = 0; nSrcStartY = 0; nSrcWidth = this->Width; nSrcHeight = this->Height;
|
|
323 |
}
|
|
324 |
else
|
|
325 |
{
|
|
326 |
nThumbWidth = Width;
|
|
327 |
nThumbHeight = Height;
|
|
328 |
if (swidth == 0 || sheight == 0)
|
|
329 |
{
|
|
330 |
nSrcStartX = 0; nSrcStartY = 0; nSrcWidth = this->Width; nSrcHeight = this->Height;
|
|
331 |
}
|
|
332 |
else
|
|
333 |
{
|
|
334 |
nSrcStartX = startX; nSrcStartY = startY;
|
|
335 |
nSrcWidth = swidth; nSrcHeight = sheight;
|
|
336 |
}
|
|
337 |
}
|
|
338 |
if (m_thumbImg.buffer&&m_thumbImg.nWidth != nThumbWidth || m_thumbImg.nHeight != nThumbHeight)
|
|
339 |
{
|
|
340 |
delete m_thumbImg.buffer; m_thumbImg.buffer = nullptr;
|
|
341 |
}
|
|
342 |
m_thumbImg.nWidth = nThumbWidth;
|
|
343 |
m_thumbImg.nHeight = nThumbHeight;
|
|
344 |
if (this->PixelFormat == MyPixelType_ARGB32)
|
|
345 |
{
|
|
346 |
if (m_thumbImg.buffer == 0)
|
|
347 |
{
|
|
348 |
m_thumbImg.buffer = new DWORD[nThumbWidth * nThumbHeight ];
|
|
349 |
}
|
|
350 |
for (int i = 0; i < nThumbHeight; i++)
|
|
351 |
{
|
|
352 |
DWORD * line1 = (DWORD *)buffer + int(i*nSrcHeight / nThumbHeight+nSrcStartY) * (Stride/4);
|
|
353 |
DWORD * tline1 = (DWORD *)m_thumbImg.buffer + i * nThumbWidth;
|
|
354 |
for (int j = 0; j < nThumbWidth; j++)
|
|
355 |
{
|
|
356 |
tline1[j] = line1[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
|
|
357 |
//tline1[j] = 255;
|
|
358 |
}
|
|
359 |
}
|
|
360 |
m_thumbImg.IsValid = 1;
|
|
361 |
}
|
|
362 |
else if (this->PixelFormat == MyPixelType_RGB8planar)
|
|
363 |
{
|
|
364 |
if (m_thumbImg.buffer == 0)
|
|
365 |
{
|
|
366 |
m_thumbImg.buffer = new DWORD[(nThumbWidth+3)/4*4 * (nThumbHeight+1)/2*2];
|
|
367 |
}
|
|
368 |
for (int i = 0; i < nThumbHeight; i++)
|
|
369 |
{
|
|
370 |
unsigned char * line1 = (unsigned char *)buffer + int(i*nSrcHeight / nThumbHeight + nSrcStartY) * (Stride);
|
|
371 |
unsigned char * line2 = (unsigned char *)buffer2 + int(i*nSrcHeight / nThumbHeight + nSrcStartY) * (Stride);
|
|
372 |
unsigned char * line3 = (unsigned char *)buffer3 + int(i*nSrcHeight / nThumbHeight + nSrcStartY) * (Stride);
|
|
373 |
|
|
374 |
|
|
375 |
DWORD * tline1 = (DWORD *)m_thumbImg.buffer + i * nThumbWidth;
|
|
376 |
for (int j = 0; j < nThumbWidth; j++)
|
|
377 |
{
|
|
378 |
COLOR * c1 = (COLOR *)&(tline1[j]);
|
|
379 |
c1->R = line1[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
|
|
380 |
c1->G = line2[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
|
|
381 |
c1->B = line3[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
|
|
382 |
|
|
383 |
//tline1[j] = 255;
|
|
384 |
}
|
|
385 |
}
|
|
386 |
m_thumbImg.IsValid = 1;
|
|
387 |
}
|
|
388 |
else if (this->PixelFormat == MyPixelType_BayerGR8 || this->PixelFormat == MyPixelType_BayerGB8)
|
|
389 |
{
|
|
390 |
if (m_thumbImg.buffer == 0)
|
|
391 |
{
|
|
392 |
m_thumbImg.buffer = new unsigned char[(nThumbWidth + 3) / 4 * 4 * (nThumbHeight + 1) / 2 * 2];
|
|
393 |
}
|
|
394 |
|
|
395 |
for (int i = 0; i < nThumbHeight; i+=2)
|
|
396 |
{
|
|
397 |
unsigned char * line1 = (unsigned char *)buffer + (int(i*nSrcHeight / nThumbHeight + nSrcStartY) & 0xfffffffe) * Stride;
|
|
398 |
unsigned char * tline1 = (unsigned char *)m_thumbImg.buffer + i * nThumbWidth;
|
|
399 |
unsigned char * line2 = (unsigned char *)buffer + ((int(i*nSrcHeight / nThumbHeight + nSrcStartY) & 0xfffffffe) + 1) * Stride;
|
|
400 |
unsigned char * tline2 = (unsigned char *)m_thumbImg.buffer + (i+1) * nThumbWidth;
|
|
401 |
|
|
402 |
for (int j = 0; j < nThumbWidth; j+=2)
|
|
403 |
{
|
|
404 |
tline1[j] = line1[int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe];
|
|
405 |
tline1[j + 1] = line1[(int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe) + 1];
|
|
406 |
tline2[j] = line2[int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe];
|
|
407 |
tline2[j + 1] = line2[(int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe) + 1];
|
|
408 |
//tline1[j] = 255;//line1[(j*this->Width / nWidth)&0xfffffffe];
|
|
409 |
//tline1[j+1] = 0;//line1[((j*this->Width / nWidth)&0xfffffffe)+1];
|
|
410 |
//tline2[j] = 0;//line2[(j*this->Width / nWidth)&0xfffffffe];
|
|
411 |
//tline2[j+1] = 255;//line2[((j*this->Width / nWidth)&0xfffffffe)+1];
|
|
412 |
}
|
|
413 |
}
|
|
414 |
m_thumbImg.IsValid = 1;
|
|
415 |
}
|
|
416 |
else
|
|
417 |
{
|
|
418 |
if (m_thumbImg.buffer == 0)
|
|
419 |
{
|
|
420 |
m_thumbImg.buffer = new unsigned char[nThumbWidth * nThumbHeight];
|
|
421 |
}
|
|
422 |
for (int i = 0; i < nThumbHeight; i++)
|
|
423 |
{
|
|
424 |
unsigned char * line1 = (unsigned char *)buffer + int(i*nSrcHeight / nThumbHeight+nSrcStartY) * Stride;
|
|
425 |
unsigned char * tline1 = (unsigned char *)m_thumbImg.buffer + i * nThumbWidth;
|
|
426 |
for (int j = 0; j < nThumbWidth; j++)
|
|
427 |
{
|
|
428 |
tline1[j] = line1[int(j*nSrcWidth / nThumbWidth+nSrcStartX)];
|
|
429 |
}
|
|
430 |
}
|
|
431 |
m_thumbImg.IsValid = 1;
|
|
432 |
}
|
|
433 |
|
|
434 |
return 0;
|
|
435 |
}
|
|
436 |
int MyImage::DrawOnWindow(HWND hWnd,int Brightness,int Contrast)
|
|
437 |
{
|
|
438 |
|
|
439 |
/*
|
|
440 |
if (this->IsHistoValid)
|
|
441 |
{
|
|
442 |
Graphics gr1(bitmap1);
|
|
443 |
Pen pen1(Color(255,255,255,255),1);
|
|
444 |
for (int i=0;i<256;i++)
|
|
445 |
{
|
|
446 |
int Length=this->HistoArray[i]*512/this->MaxHistoCount;
|
|
447 |
if (Length>255) {Length=255;}
|
|
448 |
gr1.DrawLine(&pen1,i,256,i,1);
|
|
449 |
}
|
|
450 |
}
|
|
451 |
*/
|
|
452 |
CString s1;
|
|
453 |
s1.Format(_T("SN:%d %s "),this->SN,this->Name);
|
|
454 |
s1+=InfoStr;
|
|
455 |
CString * Lable;
|
|
456 |
Lable = &s1;
|
|
457 |
// DrawBitmapOnWindow(hWnd,bitmap1,&s1,&ResultStr);
|
|
458 |
|
|
459 |
// if (bitmap1 == NULL) return 0;
|
|
460 |
if (hWnd == NULL) return 0;
|
|
461 |
if (!IsWindow(hWnd)) return 0;
|
|
462 |
if (!IsWindowVisible(hWnd)) return 0;
|
|
463 |
|
|
464 |
int srcw, srch;
|
|
465 |
srcw = this->Width;
|
|
466 |
srch = this->Height;
|
|
467 |
if (srcw == 0 || srch == 0) return 0;
|
|
468 |
|
|
469 |
RECT rect0;
|
|
470 |
GetClientRect(hWnd, &rect0);
|
|
471 |
int clientw, clienth; //客户区实际的宽度和高度
|
|
472 |
clientw = rect0.right - rect0.left;
|
|
473 |
clienth = rect0.bottom - rect0.top;
|
|
474 |
|
|
475 |
SolidBrush brush1(Color(255, 0, 0, 0)); //写黑字
|
|
476 |
SolidBrush brush2(Color(255, 255, 255, 255)); //写白字
|
|
477 |
int w1, h1; //图片在客户区显示时的宽度和高度,
|
|
478 |
//考虑到保持宽高比,与客户区大小不一定相同
|
|
479 |
int startx, starty;
|
|
480 |
//图片在客户区的起始位置;
|
|
481 |
|
|
482 |
if (srcw*rect0.bottom == srch*rect0.right)
|
|
483 |
{
|
|
484 |
w1 = clientw;
|
|
485 |
h1 = clienth;
|
|
486 |
startx = rect0.left;
|
|
487 |
starty = rect0.top;
|
|
488 |
|
|
489 |
}
|
|
490 |
else if (srcw*rect0.bottom>srch*rect0.right) //图片横向大,高度不满
|
|
491 |
{
|
|
492 |
w1 = clientw;
|
|
493 |
h1 = clientw*srch / srcw;
|
|
494 |
startx = rect0.left;
|
|
495 |
starty = rect0.top + (clienth - h1) / 2;
|
|
496 |
}
|
|
497 |
else //图片纵向大,宽度不满
|
|
498 |
{
|
|
499 |
w1 = clienth*srcw / srch;
|
|
500 |
h1 = clienth;
|
|
501 |
startx = rect0.left + (clientw - w1) / 2;
|
|
502 |
starty = rect0.top;
|
|
503 |
}
|
|
504 |
Bitmap *bitmap1 = NULL;
|
|
505 |
if (IsToRefreshCache||ShowCache != NULL && (ShowCache->GetWidth() != w1 || ShowCache->GetHeight() != h1))
|
|
506 |
{
|
|
507 |
::delete ShowCache;
|
|
508 |
ShowCache = NULL;
|
|
509 |
IsToRefreshCache = 0;
|
|
510 |
}
|
|
511 |
if (ShowCache == NULL)
|
|
512 |
{
|
|
513 |
Rect rect4;
|
|
514 |
rect4.X = 0;
|
|
515 |
rect4.Y = 0;
|
|
516 |
rect4.Width = w1;
|
|
517 |
rect4.Height = h1;
|
|
518 |
ConvertTypeToGdipBitmap32(&bitmap1, Brightness, Contrast);
|
|
519 |
ShowCache = ::new Bitmap(w1, h1);
|
|
520 |
Graphics gr4(ShowCache);
|
|
521 |
gr4.DrawImage(bitmap1,rect4);
|
|
522 |
|
|
523 |
//------------ 显示 Region
|
|
524 |
|
|
525 |
int n = myregions.size();
|
|
526 |
for (int i = 0; i < n; i++)
|
|
527 |
{
|
|
528 |
MyRegion thisregion = myregions.at(i);
|
|
529 |
int k = thisregion.pts.size();
|
|
530 |
if (thisregion.IsValid)
|
|
531 |
{
|
|
532 |
Pen pen1(Color(255,255,0,0), 1);
|
|
533 |
MyPoint lastPt = thisregion.pts.at(k - 1);
|
|
534 |
for (int j = 0; j < k; j++)
|
|
535 |
{
|
|
536 |
MyPoint pt1 = thisregion.pts.at(j);
|
|
537 |
gr4.DrawRectangle(&pen1, pt1.X*w1 / srcw - 2, pt1.Y*h1 / srch - 2 , 4, 4);
|
|
538 |
gr4.DrawLine(&pen1, pt1.X*w1 / srcw , pt1.Y*h1 / srch, lastPt.X*w1 / srcw, lastPt.Y*h1 / srch);
|
|
539 |
lastPt = pt1;
|
|
540 |
}
|
|
541 |
}
|
|
542 |
}
|
|
543 |
//-----------------------------------------------------------
|
|
544 |
///*
|
|
545 |
|
|
546 |
if (Lable != NULL&&!Lable->IsEmpty())
|
|
547 |
{
|
|
548 |
CStringW sw1;
|
|
549 |
TToW(*Lable, sw1);
|
|
550 |
// Pen pen1(Color(255,0,0,0),1); //画黑线
|
|
551 |
Pen pen2(Color(128, 128, 128, 128), 0.5); //画灰线
|
|
552 |
|
|
553 |
FontFamily fontfamily1(L"黑体");
|
|
554 |
int fontsize = h1 / 60;
|
|
555 |
if (fontsize<16) { fontsize = 16; }
|
|
556 |
Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
|
|
557 |
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
|
558 |
StringFormat stringformat1;
|
|
559 |
stringformat1.SetAlignment(StringAlignmentNear);
|
|
560 |
stringformat1.SetLineAlignment(StringAlignmentNear);
|
|
561 |
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(0.0f, 0.0f), &stringformat1, &brush1);
|
|
562 |
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(2.0f, 2.0f), &stringformat1, &brush1);
|
|
563 |
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(0.0f, 2.0f), &stringformat1, &brush1);
|
|
564 |
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(2.0f, 0.0f), &stringformat1, &brush1);
|
|
565 |
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(1.0f, 1.0f), &stringformat1, &brush2);
|
|
566 |
}
|
|
567 |
if (!ResultStr.IsEmpty())
|
|
568 |
{
|
|
569 |
CStringW sw1;
|
|
570 |
TToW(ResultStr, sw1);
|
|
571 |
// Pen pen1(Color(255,0,0,0),1); //画黑线
|
|
572 |
Pen pen2(Color(128, 128, 128, 128), 0.5); //画灰线
|
|
573 |
SolidBrush brush3(Color(255, 0, 0, 0)); //写黑字
|
|
574 |
SolidBrush brush4(Color(128, 0, 255, 0)); //写绿字
|
|
575 |
|
|
576 |
FontFamily fontfamily1(L"黑体");
|
|
577 |
int fontsize = h1 / 4;
|
|
578 |
if (fontsize<48) { fontsize = 48; }
|
|
579 |
Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
|
|
580 |
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
|
581 |
StringFormat stringformat1;
|
|
582 |
stringformat1.SetAlignment(StringAlignmentCenter);
|
|
583 |
stringformat1.SetLineAlignment(StringAlignmentCenter);
|
|
584 |
float centerx, centery;
|
|
585 |
centerx = (w1) / 2;
|
|
586 |
centery = (h1) / 2;
|
|
587 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+0.0f),&stringformat1,&brush3);
|
|
588 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+2.0f),&stringformat1,&brush3);
|
|
589 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+2.0f),&stringformat1,&brush3);
|
|
590 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+0.0f),&stringformat1,&brush3);
|
|
591 |
gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(centerx + 1.0f, centery + 1.0f), &stringformat1, &brush4);
|
|
592 |
}
|
|
593 |
|
|
594 |
gr4.Flush();
|
|
595 |
|
|
596 |
}
|
|
597 |
Rect rect1;
|
|
598 |
rect1.X = startx;
|
|
599 |
rect1.Y = starty;
|
|
600 |
rect1.Width = w1;
|
|
601 |
rect1.Height = h1;
|
|
602 |
|
|
603 |
HDC hdc1 = GetDC(hWnd);
|
|
604 |
Graphics gr1(hdc1);
|
|
605 |
|
|
606 |
gr1.DrawImage(ShowCache, rect1); //画图像
|
|
607 |
if (startx != 0) //在图像的两侧画背景
|
|
608 |
{
|
|
609 |
gr1.FillRectangle(&brush1, 0, 0, startx, clienth);
|
|
610 |
gr1.FillRectangle(&brush1, startx + w1, 0, startx, clienth);
|
|
611 |
}
|
|
612 |
if (starty != 0)
|
|
613 |
{
|
|
614 |
gr1.FillRectangle(&brush1, 0, 0, clientw, starty);
|
|
615 |
gr1.FillRectangle(&brush1, 0, starty + h1, clientw, starty);
|
|
616 |
}
|
|
617 |
|
|
618 |
// gr1.Flush();
|
|
619 |
//*/
|
|
620 |
ReleaseDC(hWnd, hdc1);
|
|
621 |
|
|
622 |
if (bitmap1!=NULL) ::delete bitmap1;
|
|
623 |
return 1;
|
|
624 |
};
|
|
625 |
int MyImage::DrawThumbOnWindow(HWND hWnd, int Brightness, int Contrast)
|
|
626 |
{
|
|
627 |
if (!m_thumbImg.IsValid) CreateThumbImg();
|
|
628 |
Bitmap *bitmap1 = NULL;
|
|
629 |
ConvertThumbToGdipBitmap32(&bitmap1, Brightness, Contrast);
|
|
630 |
/*
|
|
631 |
if (this->IsHistoValid)
|
|
632 |
{
|
|
633 |
Graphics gr1(bitmap1);
|
|
634 |
Pen pen1(Color(255,255,255,255),1);
|
|
635 |
for (int i=0;i<256;i++)
|
|
636 |
{
|
|
637 |
int Length=this->HistoArray[i]*512/this->MaxHistoCount;
|
|
638 |
if (Length>255) {Length=255;}
|
|
639 |
gr1.DrawLine(&pen1,i,256,i,1);
|
|
640 |
}
|
|
641 |
}
|
|
642 |
*/
|
|
643 |
CString s1;
|
|
644 |
s1.Format(_T("SN:%d %s "), this->SN, this->Name);
|
|
645 |
s1 += InfoStr;
|
|
646 |
DrawBitmapOnWindow(hWnd, bitmap1, &s1, &ResultStr);
|
|
647 |
::delete bitmap1;
|
|
648 |
return 1;
|
|
649 |
};
|
|
650 |
int MyImage::ConvertTypeToGdipBitmap32(Gdiplus::Bitmap** bitmapdest,int Brightness,int Contrast)
|
|
651 |
{
|
|
652 |
/*
|
|
653 |
PixelType_Mono8
|
|
654 |
PixelType_BayerGB8
|
|
655 |
PixelType_BayerGB12
|
|
656 |
PixelType_YUV422packed
|
|
657 |
PixelType_YUV422_YUYV_Packed
|
|
658 |
PixelType_BayerGB12Packed
|
|
659 |
*/
|
|
660 |
int i,j,k,l;
|
|
661 |
int w,h;
|
|
662 |
w=this->Width;
|
|
663 |
h=this->Height;
|
|
664 |
int pixeltype;
|
|
665 |
pixeltype=this->PixelFormat;
|
|
666 |
if (*bitmapdest==NULL)
|
|
667 |
{
|
|
668 |
*bitmapdest=::new Gdiplus::Bitmap(w,h);
|
|
669 |
}
|
|
670 |
else if ((*bitmapdest)->GetWidth()!=w&&(*bitmapdest)->GetHeight()!=h)
|
|
671 |
{
|
|
672 |
::delete *bitmapdest;*bitmapdest=NULL;
|
|
673 |
*bitmapdest=::new Gdiplus::Bitmap(w,h);
|
|
674 |
}
|
|
675 |
|
|
676 |
unsigned char * srcpixel=(unsigned char *)buffer;
|
|
677 |
Gdiplus::BitmapData bitmapdata1;
|
|
678 |
bitmapdata1.PixelFormat=PixelFormat32bppRGB;
|
|
679 |
Gdiplus::Rect rect1(0,0,w,h);
|
|
680 |
Gdiplus::Status GdipStatus=(*bitmapdest)->LockBits(&rect1,Gdiplus::ImageLockModeWrite,//|ImageLockModeUserInputBuf,
|
|
681 |
PixelFormat32bppRGB,&bitmapdata1);//PixelFormat32bppRGB
|
|
682 |
if (GdipStatus!=Gdiplus::Ok)
|
|
683 |
{
|
|
684 |
CString Errs1;
|
|
685 |
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
|
686 |
// SysLog(Errs1);
|
|
687 |
return 0;
|
|
688 |
}
|
|
689 |
COLOR c1;
|
|
690 |
UINT * pixels;
|
|
691 |
pixels=(UINT *)bitmapdata1.Scan0;
|
|
692 |
int s=bitmapdata1.Stride;
|
|
693 |
|
|
694 |
|
|
695 |
if (pixeltype==MyPixelType_Mono8)
|
|
696 |
{
|
|
697 |
for (i=0;i<h;i++)
|
|
698 |
{
|
|
699 |
k=i*(int)Stride;
|
|
700 |
l=i*s/4;
|
|
701 |
for (j=0;j<w;j++)
|
|
702 |
{
|
|
703 |
c1.R=srcpixel[k+j];
|
|
704 |
c1.G=c1.R;
|
|
705 |
c1.B=c1.R;
|
|
706 |
pixels[l+j]=c1.argb;
|
|
707 |
}
|
|
708 |
}
|
|
709 |
}
|
|
710 |
if (pixeltype==MyPixelType_ARGB32)
|
|
711 |
{
|
|
712 |
memcpy(pixels,buffer,h*Stride);
|
|
713 |
}
|
|
714 |
if (pixeltype==MyPixelType_BayerGR8)
|
|
715 |
{
|
|
716 |
BayerGR8toRGB32(buffer,bitmapdata1.Scan0,w,h,Stride,bitmapdata1.Stride);
|
|
717 |
}
|
|
718 |
if (pixeltype==MyPixelType_BayerGB8)
|
|
719 |
{
|
|
720 |
BayerGB8toRGB32(buffer,bitmapdata1.Scan0,w,h,Stride,bitmapdata1.Stride);
|
|
721 |
}
|
|
722 |
if (pixeltype==MyPixelType_BayerGB12)
|
|
723 |
{
|
|
724 |
Gdiplus::Bitmap* bitmapRaw8=NULL;
|
|
725 |
|
|
726 |
if (bitmapRaw8==NULL)
|
|
727 |
{
|
|
728 |
bitmapRaw8=::new Gdiplus::Bitmap(w,h,PixelFormat8bppIndexed);
|
|
729 |
}
|
|
730 |
if (bitmapRaw8->GetHeight()!=h||bitmapRaw8->GetWidth()!=w)
|
|
731 |
{
|
|
732 |
::delete bitmapRaw8;
|
|
733 |
bitmapRaw8=::new Gdiplus::Bitmap(w,h,PixelFormat8bppIndexed);
|
|
734 |
}
|
|
735 |
Gdiplus::ColorPalette * pal1=(Gdiplus::ColorPalette *) new unsigned char[1048];
|
|
736 |
pal1->Flags=2;
|
|
737 |
pal1->Count=256;
|
|
738 |
int i;
|
|
739 |
for (i=0;i<256;i++)
|
|
740 |
{
|
|
741 |
pal1->Entries[i]=Gdiplus::Color::MakeARGB(255,i,i,i);
|
|
742 |
}
|
|
743 |
|
|
744 |
bitmapRaw8->SetPalette(pal1);
|
|
745 |
delete [] pal1;
|
|
746 |
|
|
747 |
Gdiplus::Rect rect1(0,0,w,h);
|
|
748 |
Gdiplus::BitmapData bitmapdataRaw8;
|
|
749 |
bitmapdataRaw8.PixelFormat=PixelFormat8bppIndexed;
|
|
750 |
Gdiplus::Status GdipStatus=bitmapRaw8->LockBits(&rect1,Gdiplus::ImageLockModeWrite,PixelFormat8bppIndexed,&bitmapdataRaw8);
|
|
751 |
if (GdipStatus!=Gdiplus::Ok)
|
|
752 |
{
|
|
753 |
CString Errs1;
|
|
754 |
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
|
755 |
// SysLog(Errs1);
|
|
756 |
return 0;
|
|
757 |
}
|
|
758 |
Raw12ToRaw8(bitmapdataRaw8.Scan0,srcpixel,w,h);
|
|
759 |
bitmapRaw8->UnlockBits(&bitmapdataRaw8);
|
|
760 |
|
|
761 |
unsigned short *srcpixel2=(unsigned short *) srcpixel;
|
|
762 |
int r,g,b;
|
|
763 |
for (i=0;i<h;i+=2)
|
|
764 |
{
|
|
765 |
k=i*(int)Stride/2;
|
|
766 |
l=i*s/4;
|
|
767 |
|
|
768 |
//偶数行
|
|
769 |
for (j=0;j<w;j+=2)
|
|
770 |
{
|
|
771 |
g=srcpixel2[k+j];
|
|
772 |
b=srcpixel2[k+j+1];
|
|
773 |
r=srcpixel2[k+Stride/2+j];
|
|
774 |
c1.R=r>>4;
|
|
775 |
c1.G=g>>4;
|
|
776 |
c1.B=b>>4;
|
|
777 |
pixels[l+j]=c1.argb;
|
|
778 |
pixels[l+j+1]=c1.argb;
|
|
779 |
}
|
|
780 |
//奇数行
|
|
781 |
for (j=0;j<w;j+=2)
|
|
782 |
{
|
|
783 |
g=srcpixel2[k+Stride/2+j+1];
|
|
784 |
b=srcpixel2[k+j+1];
|
|
785 |
r=srcpixel2[k+Stride/2+j];
|
|
786 |
c1.R=r>>4;
|
|
787 |
c1.G=g>>4;
|
|
788 |
c1.B=b>>4;
|
|
789 |
pixels[l+s/4+j]=c1.argb;
|
|
790 |
pixels[l+s/4+j+1]=c1.argb;
|
|
791 |
}
|
|
792 |
}
|
|
793 |
}
|
|
794 |
if (pixeltype==MyPixelType_YUV422packed)
|
|
795 |
{
|
|
796 |
int y,u,v;
|
|
797 |
int r,g,b;
|
|
798 |
for (i=0;i<h;i++)
|
|
799 |
{
|
|
800 |
k=i*(int)Stride;
|
|
801 |
l=i*s/4;
|
|
802 |
for (j=0;j<w;j+=2)
|
|
803 |
{
|
|
804 |
y=srcpixel[k+j*2+1];
|
|
805 |
u=srcpixel[k+(j/2)*4];
|
|
806 |
v=srcpixel[k+(j/2)*4+2];
|
|
807 |
r=int(y+1.402*(v-128));
|
|
808 |
g=int(y-0.34414*(u-128)-0.71414*(v-128));
|
|
809 |
b=int(y+1.772*(u-128));
|
|
810 |
if (r<0){r=0;}
|
|
811 |
if (g<0) {g=0;}
|
|
812 |
if (b<0) {b=0;}
|
|
813 |
|
|
814 |
if (r>255){r=255;}
|
|
815 |
if (g>255){g=255;}
|
|
816 |
if (b>255) {b=255;}
|
|
817 |
c1.R=r;
|
|
818 |
c1.G=g;
|
|
819 |
c1.B=b;
|
|
820 |
pixels[l+j]=c1.argb;
|
|
821 |
|
|
822 |
y=srcpixel[k+j*2+3];
|
|
823 |
r=int(y+1.402*(v-128));
|
|
824 |
g=int(y-0.34414*(u-128)-0.71414*(v-128));
|
|
825 |
b=int(y+1.772*(u-128));
|
|
826 |
if (r<0){r=0;}
|
|
827 |
if (g<0) {g=0;}
|
|
828 |
if (b<0) {b=0;}
|
|
829 |
|
|
830 |
if (r>255){r=255;}
|
|
831 |
if (g>255){g=255;}
|
|
832 |
if (b>255) {b=255;}
|
|
833 |
|
|
834 |
c1.R=r;
|
|
835 |
c1.G=g;
|
|
836 |
c1.B=b;
|
|
837 |
pixels[l+j+1]=c1.argb;
|
|
838 |
}
|
|
839 |
}
|
|
840 |
}
|
|
841 |
|
|
842 |
if (pixeltype==MyPixelType_YUV422_YUYV_Packed)
|
|
843 |
{
|
|
844 |
int y,u,v;
|
|
845 |
int r,g,b;
|
|
846 |
for (i=0;i<h;i++)
|
|
847 |
{
|
|
848 |
k=i*(int)Stride;
|
|
849 |
l=i*s/4;
|
|
850 |
for (j=0;j<w;j+=2)
|
|
851 |
{
|
|
852 |
y=srcpixel[k+j*2];
|
|
853 |
u=srcpixel[k+(j/2)*4+1];
|
|
854 |
v=srcpixel[k+(j/2)*4+3];
|
|
855 |
r=int(y+1.402*(v-128));
|
|
856 |
g=int(y-0.34414*(u-128)-0.71414*(v-128));
|
|
857 |
b=int(y+1.772*(u-128));
|
|
858 |
if (r<0){r=0;}
|
|
859 |
if (g<0) {g=0;}
|
|
860 |
if (b<0) {b=0;}
|
|
861 |
c1.R=(r>255?255:r);
|
|
862 |
c1.G=(g>255?255:g);
|
|
863 |
c1.B=(b>255?255:b);
|
|
864 |
pixels[l+j]=c1.argb;
|
|
865 |
|
|
866 |
y=srcpixel[k+j*2+2];
|
|
867 |
r=int(y+1.402*(v-128));
|
|
868 |
g=int(y-0.34414*(u-128)-0.71414*(v-128));
|
|
869 |
b=int(y+1.772*(u-128));
|
|
870 |
if (r<0){r=0;}
|
|
871 |
if (g<0) {g=0;}
|
|
872 |
if (b<0) {b=0;}
|
|
873 |
c1.R=(r>255?255:r);
|
|
874 |
c1.G=(g>255?255:g);
|
|
875 |
c1.B=(b>255?255:b);
|
|
876 |
pixels[l+j+1]=c1.argb;
|
|
877 |
}
|
|
878 |
}
|
|
879 |
}
|
|
880 |
//*/
|
|
881 |
if (this->PixelFormat==MyPixelType_BayerGB12_Packed)
|
|
882 |
{
|
|
883 |
//unsigned short *srcpixel2=(unsigned short *) srcpixel;
|
|
884 |
/*
|
|
885 |
int r,g,b;
|
|
886 |
for (i=0;i<h;i+=2)
|
|
887 |
{
|
|
888 |
k=i*(int)stride;
|
|
889 |
l=i*s/4;
|
|
890 |
//偶数行
|
|
891 |
for (j=0;j<w;j+=2)
|
|
892 |
{
|
|
893 |
g=((unsigned int)(srcpixel[k+j*3/2]&0xff)<<4)+((unsigned int)(srcpixel[k+j*3/2+1]&0xf)); //
|
|
894 |
b=((unsigned int)(srcpixel[k+j*3/2+1]&0xf0)>>4)+(((unsigned int)srcpixel[k+j*3/2+2]&0xff)<<4);
|
|
895 |
r=((unsigned int)srcpixel[k+stride+j*3/2]<<4)+((unsigned int)(srcpixel[k+stride+j*3/2+1]&0xf));
|
|
896 |
//b=g;
|
|
897 |
//r=g;
|
|
898 |
c1.R=r>>4;
|
|
899 |
c1.G=g>>4;
|
|
900 |
c1.B=b>>4;
|
|
901 |
pixels[l+j]=c1.argb;
|
|
902 |
pixels[l+j+1]=c1.argb;
|
|
903 |
}
|
|
904 |
//奇数行
|
|
905 |
for (j=0;j<w;j+=2)
|
|
906 |
{
|
|
907 |
g=((unsigned int)(srcpixel[k+stride+j*3/2+2]&0xff)<<4)+((unsigned int)(srcpixel[k+stride+j*3/2+1]&0xf));
|
|
908 |
b=((unsigned int)(srcpixel[k+j*3/2+1]&0xf0)>>4)+((unsigned int)(srcpixel[k+j*3/2+2]&0xff)<<4);
|
|
909 |
r=((unsigned int)srcpixel[k+stride+j*3/2]<<4)+((unsigned int)(srcpixel[k+stride+j*3/2+1]&0xf));
|
|
910 |
c1.R=r>>4;
|
|
911 |
c1.G=g>>4;
|
|
912 |
c1.B=b>>4;
|
|
913 |
pixels[l+s/4+j]=c1.argb;
|
|
914 |
pixels[l+s/4+j+1]=c1.argb;
|
|
915 |
}
|
|
916 |
}
|
|
917 |
*/
|
|
918 |
double SysGamma=1.0f;
|
|
919 |
BayerGB12PackedToRGB32(pixels,srcpixel,w,h,(float)SysGamma);
|
|
920 |
}
|
|
921 |
(*bitmapdest)->UnlockBits(&bitmapdata1);
|
|
922 |
return 1;
|
|
923 |
}
|
|
924 |
|
|
925 |
int MyImage::ConvertThumbToGdipBitmap32(Gdiplus::Bitmap** bitmapdest, int Brightness, int Contrast)
|
|
926 |
{
|
|
927 |
/*
|
|
928 |
PixelType_Mono8
|
|
929 |
PixelType_BayerGB8
|
|
930 |
PixelType_BayerGB12
|
|
931 |
PixelType_YUV422packed
|
|
932 |
PixelType_YUV422_YUYV_Packed
|
|
933 |
PixelType_BayerGB12Packed
|
|
934 |
*/
|
|
935 |
int i, j, k, l;
|
|
936 |
int w, h;
|
|
937 |
w = m_thumbImg.nWidth;
|
|
938 |
h = m_thumbImg.nHeight;
|
|
939 |
int pixeltype;
|
|
940 |
pixeltype = this->PixelFormat;
|
|
941 |
|
|
942 |
if (*bitmapdest == NULL)
|
|
943 |
{
|
|
944 |
*bitmapdest = ::new Gdiplus::Bitmap(w, h);
|
|
945 |
}
|
|
946 |
else if ((*bitmapdest)->GetWidth() != w && (*bitmapdest)->GetHeight() != h)
|
|
947 |
{
|
|
948 |
::delete *bitmapdest; *bitmapdest = NULL;
|
|
949 |
*bitmapdest = ::new Gdiplus::Bitmap(w, h);
|
|
950 |
}
|
|
951 |
|
|
952 |
unsigned char * srcpixel = (unsigned char *)m_thumbImg.buffer;
|
|
953 |
Gdiplus::BitmapData bitmapdata1;
|
|
954 |
bitmapdata1.PixelFormat = PixelFormat32bppRGB;
|
|
955 |
Gdiplus::Rect rect1(0, 0, w, h);
|
|
956 |
Gdiplus::Status GdipStatus = (*bitmapdest)->LockBits(&rect1, Gdiplus::ImageLockModeWrite,//|ImageLockModeUserInputBuf,
|
|
957 |
PixelFormat32bppRGB, &bitmapdata1);//PixelFormat32bppRGB
|
|
958 |
if (GdipStatus != Gdiplus::Ok)
|
|
959 |
{
|
|
960 |
CString Errs1;
|
|
961 |
Errs1.Format(_T("Gdip LockBits Error %d \r\n"), GdipStatus);
|
|
962 |
// SysLog(Errs1);
|
|
963 |
return 0;
|
|
964 |
}
|
|
965 |
COLOR c1;
|
|
966 |
UINT * pixels;
|
|
967 |
pixels = (UINT *)bitmapdata1.Scan0;
|
|
968 |
int s = bitmapdata1.Stride;
|
|
969 |
|
|
970 |
|
|
971 |
if (pixeltype == MyPixelType_Mono8)
|
|
972 |
{
|
|
973 |
for (i = 0; i<h; i++)
|
|
974 |
{
|
|
975 |
k = i*(int)m_thumbImg.nWidth;
|
|
976 |
l = i*s / 4;
|
|
977 |
for (j = 0; j<w; j++)
|
|
978 |
{
|
|
979 |
c1.R = srcpixel[k + j];
|
|
980 |
c1.G = c1.R;
|
|
981 |
c1.B = c1.R;
|
|
982 |
c1.A = 255;
|
|
983 |
pixels[l + j] = c1.argb;
|
|
984 |
}
|
|
985 |
}
|
|
986 |
}
|
|
987 |
if (pixeltype == MyPixelType_ARGB32 || pixeltype == MyPixelType_RGB8planar)
|
|
988 |
{
|
|
989 |
memcpy(pixels, m_thumbImg.buffer, h*w * 4);
|
|
990 |
}
|
|
991 |
if (pixeltype == MyPixelType_BayerGR8)
|
|
992 |
{
|
|
993 |
BayerGR8toRGB32(m_thumbImg.buffer, bitmapdata1.Scan0, w, h, w, bitmapdata1.Stride);
|
|
994 |
}
|
|
995 |
if (pixeltype == MyPixelType_BayerGB8)
|
|
996 |
{
|
|
997 |
BayerGB8toRGB32(m_thumbImg.buffer, bitmapdata1.Scan0, w, h, w, bitmapdata1.Stride);
|
|
998 |
}
|
|
999 |
(*bitmapdest)->UnlockBits(&bitmapdata1);
|
|
1000 |
return 1;
|
|
1001 |
}
|
|
1002 |
|
|
1003 |
int GdipDrawRoundRect(Gdiplus::Graphics &gr1, Gdiplus::Pen &pen1, int x1, int y1, int x2, int y2, int r)
|
|
1004 |
{
|
|
1005 |
gr1.DrawLine(&pen1,x1+r,y1,x2-r,y1);
|
|
1006 |
gr1.DrawLine(&pen1,x1+r,y2,x2-r,y2);
|
|
1007 |
gr1.DrawLine(&pen1,x1,y1+r,x1,y2-r);
|
|
1008 |
gr1.DrawLine(&pen1,x2,y1+r,x2,y2-r);
|
|
1009 |
gr1.DrawArc(&pen1,x1,y1,r*2,r*2,180,90);
|
|
1010 |
gr1.DrawArc(&pen1,x2-2*r,y1,r*2,r*2,270,90);
|
|
1011 |
gr1.DrawArc(&pen1,x1,y2-r*2,r*2,r*2,90,90);
|
|
1012 |
gr1.DrawArc(&pen1,x2-r*2,y2-r*2,r*2,r*2,0,90);
|
|
1013 |
return 1;
|
|
1014 |
}
|
|
1015 |
|
|
1016 |
int SaveBufferToFile(void * pBuf, size_t nSize, CString sFilePathName)
|
|
1017 |
{
|
|
1018 |
CString sFilePath;
|
|
1019 |
int j;
|
|
1020 |
j = sFilePathName.ReverseFind(_T('\\'));
|
|
1021 |
sFilePath = sFilePathName.Left(j);
|
|
1022 |
SHCreateDirectoryEx(NULL, sFilePath, NULL);
|
|
1023 |
CFile file1;
|
|
1024 |
CFileException e1;
|
|
1025 |
j = file1.Open(sFilePathName, CFile::modeWrite | CFile::modeCreate, NULL, &e1);
|
|
1026 |
if (!j) { return 0; }
|
|
1027 |
file1.Write(pBuf, nSize);
|
|
1028 |
file1.Close();
|
|
1029 |
return 1;
|
|
1030 |
}
|
|
1031 |
|
|
1032 |
int SaveBufferToBmpFile(void * buf1,int width, int height, int stride, CString FilePathName,LONG XPelsPerMeter,LONG YPelsPerMeter)
|
|
1033 |
{
|
|
1034 |
//分解文件路径和文件名
|
|
1035 |
CString sFilePath;
|
|
1036 |
int j;
|
|
1037 |
j=FilePathName.ReverseFind(_T('\\'));
|
|
1038 |
sFilePath=FilePathName.Left(j);
|
|
1039 |
//检查是否有可用的磁盘空间
|
|
1040 |
ULARGE_INTEGER luse;
|
|
1041 |
ULARGE_INTEGER ltotal;
|
|
1042 |
ULARGE_INTEGER lfree;
|
|
1043 |
|
|
1044 |
double fuse,ftotal,ffree;
|
|
1045 |
GetDiskFreeSpaceEx(sFilePath,&luse,<otal,&lfree);
|
|
1046 |
fuse=luse.QuadPart/1024.0/1024.0/1024.0;
|
|
1047 |
ftotal=ltotal.QuadPart/1048576.0/1024.0;
|
|
1048 |
ffree=lfree.QuadPart/1048576.0/1024.0;
|
|
1049 |
if (fuse<1.0) {return false;} //如果可用空间小于1G,那么不存储文件。
|
|
1050 |
//创建目录
|
|
1051 |
SHCreateDirectoryEx(NULL,sFilePath,NULL);
|
|
1052 |
|
|
1053 |
//开始创建位图文件
|
|
1054 |
long newStride;
|
|
1055 |
newStride=((width+3)&0xfffc);
|
|
1056 |
BITMAPFILEHEADER header1;
|
|
1057 |
// BITMAPINFO info1;
|
|
1058 |
BITMAPINFOHEADER infoheader1;
|
|
1059 |
// RGBQUAD buf[256];
|
|
1060 |
header1.bfType=0x4d42;
|
|
1061 |
header1.bfSize=newStride*height+1078;
|
|
1062 |
header1.bfReserved1=0;
|
|
1063 |
header1.bfReserved2=0;
|
|
1064 |
header1.bfOffBits=1078;
|
|
1065 |
|
|
1066 |
infoheader1.biSize=40;
|
|
1067 |
infoheader1.biWidth=width;
|
|
1068 |
infoheader1.biHeight=height;
|
|
1069 |
infoheader1.biPlanes=1;
|
|
1070 |
infoheader1.biBitCount=8;
|
|
1071 |
infoheader1.biCompression=BI_RGB;
|
|
1072 |
infoheader1.biSizeImage=0;
|
|
1073 |
infoheader1.biXPelsPerMeter=XPelsPerMeter;
|
|
1074 |
infoheader1.biYPelsPerMeter=YPelsPerMeter;
|
|
1075 |
infoheader1.biClrUsed=0;
|
|
1076 |
infoheader1.biClrImportant=0;
|
|
1077 |
RGBQUAD pallette[256];
|
|
1078 |
|
|
1079 |
for (int i=0;i<256;i++)
|
|
1080 |
{
|
|
1081 |
pallette[i].rgbBlue=i;
|
|
1082 |
pallette[i].rgbGreen=i;
|
|
1083 |
pallette[i].rgbRed=i;
|
|
1084 |
pallette[i].rgbReserved=0;
|
|
1085 |
}
|
|
1086 |
|
|
1087 |
CFile file1;
|
|
1088 |
CFileException e1;
|
|
1089 |
j=file1.Open(FilePathName,CFile::modeWrite|CFile::modeCreate,NULL,&e1);
|
|
1090 |
if (!j) {return 0;}
|
|
1091 |
file1.Write(&header1,sizeof(header1));
|
|
1092 |
file1.Write(&infoheader1,sizeof(infoheader1));
|
|
1093 |
file1.Write(pallette,1024);
|
|
1094 |
for (int i=0;i<height;i++)
|
|
1095 |
{
|
|
1096 |
file1.Write((char *)buf1+(height-i-1)*stride,newStride);
|
|
1097 |
}
|
|
1098 |
file1.Close();
|
|
1099 |
return true;
|
|
1100 |
}
|
|
1101 |
|
|
1102 |
int DrawBitmapOnWindow(HWND DestWindow,Bitmap* srcbitmap,CString * Lable, CString * ResultStr, double scale)
|
|
1103 |
{
|
|
1104 |
if (srcbitmap==NULL) return 0;
|
|
1105 |
if (DestWindow==NULL) return 0;
|
|
1106 |
if (!IsWindow(DestWindow)) return 0;
|
|
1107 |
if (!IsWindowVisible(DestWindow)) return 0;
|
|
1108 |
|
|
1109 |
int srcw,srch;
|
|
1110 |
srcw=srcbitmap->GetWidth();
|
|
1111 |
srch=srcbitmap->GetHeight();
|
|
1112 |
|
|
1113 |
HDC hdc1=GetDC(DestWindow);
|
|
1114 |
Graphics gr1(hdc1);
|
|
1115 |
RECT rect0;
|
|
1116 |
GetClientRect(DestWindow,&rect0);
|
|
1117 |
int clientw,clienth; //客户区实际的宽度和高度
|
|
1118 |
clientw=rect0.right-rect0.left;
|
|
1119 |
clienth=rect0.bottom-rect0.top;
|
|
1120 |
|
|
1121 |
|
|
1122 |
int w1,h1; //图片在客户区显示时的宽度和高度,
|
|
1123 |
//考虑到保持宽高比,与客户区大小不一定相同
|
|
1124 |
int startx,starty;
|
|
1125 |
//图片在客户区的起始位置;
|
|
1126 |
|
|
1127 |
if (srcw*rect0.bottom==srch*rect0.right)
|
|
1128 |
{
|
|
1129 |
w1=clientw;
|
|
1130 |
h1=clienth;
|
|
1131 |
startx=rect0.left;
|
|
1132 |
starty=rect0.top;
|
|
1133 |
|
|
1134 |
}else if (srcw*rect0.bottom>srch*rect0.right) //图片横向大,高度不满
|
|
1135 |
{
|
|
1136 |
w1=clientw;
|
|
1137 |
h1=clientw*srch/srcw;
|
|
1138 |
startx=rect0.left;
|
|
1139 |
starty=rect0.top+(clienth-h1)/2;
|
|
1140 |
}
|
|
1141 |
else //图片纵向大,宽度不满
|
|
1142 |
{
|
|
1143 |
w1=clienth*srcw/srch;
|
|
1144 |
h1=clienth;
|
|
1145 |
startx=rect0.left+(clientw-w1)/2;
|
|
1146 |
starty=rect0.top;
|
|
1147 |
}
|
|
1148 |
Rect rect1;
|
|
1149 |
rect1.X=startx;
|
|
1150 |
rect1.Y=starty;
|
|
1151 |
rect1.Width=w1;
|
|
1152 |
rect1.Height=h1;
|
|
1153 |
|
|
1154 |
SolidBrush brush1(Color(255,0,0,0)); //写黑字
|
|
1155 |
SolidBrush brush2(Color(255,255,255,255)); //写白字
|
|
1156 |
|
|
1157 |
gr1.DrawImage(srcbitmap,rect1); //画图像
|
|
1158 |
if (startx!=0) //在图像的两侧画背景
|
|
1159 |
{
|
|
1160 |
gr1.FillRectangle(&brush1,0,0,startx,clienth);
|
|
1161 |
gr1.FillRectangle(&brush1,startx+w1,0,startx,clienth);
|
|
1162 |
}
|
|
1163 |
if (starty!=0)
|
|
1164 |
{
|
|
1165 |
gr1.FillRectangle(&brush1,0,0,clientw,starty);
|
|
1166 |
gr1.FillRectangle(&brush1,0,starty+h1,clientw,starty);
|
|
1167 |
}
|
|
1168 |
///*
|
|
1169 |
if (Lable!=NULL&&!Lable->IsEmpty())
|
|
1170 |
{
|
|
1171 |
CStringW sw1;
|
|
1172 |
TToW(*Lable,sw1);
|
|
1173 |
// Pen pen1(Color(255,0,0,0),1); //画黑线
|
|
1174 |
Pen pen2(Color(128,128,128,128),0.5); //画灰线
|
|
1175 |
|
|
1176 |
FontFamily fontfamily1(L"黑体");
|
|
1177 |
int fontsize=h1/60;
|
|
1178 |
if (fontsize<16) {fontsize=16;}
|
|
1179 |
Gdiplus::Font font1(&fontfamily1,fontsize,FontStyleRegular);
|
|
1180 |
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
|
1181 |
StringFormat stringformat1;
|
|
1182 |
stringformat1.SetAlignment(StringAlignmentNear);
|
|
1183 |
stringformat1.SetLineAlignment(StringAlignmentNear);
|
|
1184 |
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+0.0f,starty+0.0f),&stringformat1,&brush1);
|
|
1185 |
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+2.0f,starty+2.0f),&stringformat1,&brush1);
|
|
1186 |
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+0.0f,starty+2.0f),&stringformat1,&brush1);
|
|
1187 |
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+2.0f,starty+0.0f),&stringformat1,&brush1);
|
|
1188 |
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+1.0f,starty+1.0f),&stringformat1,&brush2);
|
|
1189 |
}
|
|
1190 |
if (ResultStr!=NULL&&!ResultStr->IsEmpty())
|
|
1191 |
{
|
|
1192 |
CStringW sw1;
|
|
1193 |
TToW(*ResultStr,sw1);
|
|
1194 |
// Pen pen1(Color(255,0,0,0),1); //画黑线
|
|
1195 |
Pen pen2(Color(128,128,128,128),0.5); //画灰线
|
|
1196 |
SolidBrush brush3(Color(255,0,0,0)); //写黑字
|
|
1197 |
SolidBrush brush4(Color(128,0,255,0)); //写绿字
|
|
1198 |
|
|
1199 |
FontFamily fontfamily1(L"黑体");
|
|
1200 |
int fontsize=h1/4;
|
|
1201 |
if (fontsize<48) {fontsize=48;}
|
|
1202 |
Gdiplus::Font font1(&fontfamily1,fontsize,FontStyleRegular);
|
|
1203 |
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
|
1204 |
StringFormat stringformat1;
|
|
1205 |
stringformat1.SetAlignment(StringAlignmentCenter);
|
|
1206 |
stringformat1.SetLineAlignment(StringAlignmentCenter);
|
|
1207 |
float centerx,centery;
|
|
1208 |
centerx=(rect0.right+rect0.left)/2;
|
|
1209 |
centery=(rect0.top+rect0.bottom)/2;
|
|
1210 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+0.0f),&stringformat1,&brush3);
|
|
1211 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+2.0f),&stringformat1,&brush3);
|
|
1212 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+2.0f),&stringformat1,&brush3);
|
|
1213 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+0.0f),&stringformat1,&brush3);
|
|
1214 |
gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+1.0f,centery+1.0f),&stringformat1,&brush4);
|
|
1215 |
}
|
|
1216 |
// gr1.Flush();
|
|
1217 |
//*/
|
|
1218 |
ReleaseDC(DestWindow,hdc1);
|
|
1219 |
return 0;
|
|
1220 |
}
|
|
1221 |
int DrawImageOnWindow(HWND DestWindow, Image* srcimage, CString * Lable, CString * ResultStr, double scale)
|
|
1222 |
{
|
|
1223 |
if (srcimage == NULL) return 0;
|
|
1224 |
if (DestWindow == NULL) return 0;
|
|
1225 |
if (!IsWindow(DestWindow)) return 0;
|
|
1226 |
if (!IsWindowVisible(DestWindow)) return 0;
|
|
1227 |
|
|
1228 |
int srcw, srch;
|
|
1229 |
srcw = srcimage->GetWidth();
|
|
1230 |
srch = srcimage->GetHeight();
|
|
1231 |
|
|
1232 |
HDC hdc1 = GetDC(DestWindow);
|
|
1233 |
Graphics gr1(hdc1);
|
|
1234 |
RECT rect0;
|
|
1235 |
GetClientRect(DestWindow, &rect0);
|
|
1236 |
int clientw, clienth; //客户区实际的宽度和高度
|
|
1237 |
clientw = rect0.right - rect0.left;
|
|
1238 |
clienth = rect0.bottom - rect0.top;
|
|
1239 |
|
|
1240 |
|
|
1241 |
int w1, h1; //图片在客户区显示时的宽度和高度,
|
|
1242 |
//考虑到保持宽高比,与客户区大小不一定相同
|
|
1243 |
int startx, starty;
|
|
1244 |
//图片在客户区的起始位置;
|
|
1245 |
|
|
1246 |
if (srcw*rect0.bottom == srch*rect0.right)
|
|
1247 |
{
|
|
1248 |
w1 = clientw;
|
|
1249 |
h1 = clienth;
|
|
1250 |
startx = rect0.left;
|
|
1251 |
starty = rect0.top;
|
|
1252 |
|
|
1253 |
}
|
|
1254 |
else if (srcw*rect0.bottom>srch*rect0.right) //图片横向大,高度不满
|
|
1255 |
{
|
|
1256 |
w1 = clientw;
|
|
1257 |
h1 = clientw*srch / srcw;
|
|
1258 |
startx = rect0.left;
|
|
1259 |
starty = rect0.top + (clienth - h1) / 2;
|
|
1260 |
}
|
|
1261 |
else //图片纵向大,宽度不满
|
|
1262 |
{
|
|
1263 |
w1 = clienth*srcw / srch;
|
|
1264 |
h1 = clienth;
|
|
1265 |
startx = rect0.left + (clientw - w1) / 2;
|
|
1266 |
starty = rect0.top;
|
|
1267 |
}
|
|
1268 |
Rect rect1;
|
|
1269 |
rect1.X = startx;
|
|
1270 |
rect1.Y = starty;
|
|
1271 |
rect1.Width = w1;
|
|
1272 |
rect1.Height = h1;
|
|
1273 |
|
|
1274 |
SolidBrush brush1(Color(255, 0, 0, 0)); //写黑字
|
|
1275 |
SolidBrush brush2(Color(255, 255, 255, 255)); //写白字
|
|
1276 |
|
|
1277 |
gr1.DrawImage(srcimage, rect1); //画图像
|
|
1278 |
if (startx != 0) //在图像的两侧画背景
|
|
1279 |
{
|
|
1280 |
gr1.FillRectangle(&brush1, 0, 0, startx, clienth);
|
|
1281 |
gr1.FillRectangle(&brush1, startx + w1, 0, startx, clienth);
|
|
1282 |
}
|
|
1283 |
if (starty != 0)
|
|
1284 |
{
|
|
1285 |
gr1.FillRectangle(&brush1, 0, 0, clientw, starty);
|
|
1286 |
gr1.FillRectangle(&brush1, 0, starty + h1, clientw, starty);
|
|
1287 |
}
|
|
1288 |
|
|
1289 |
if (Lable != NULL&&!Lable->IsEmpty())
|
|
1290 |
{
|
|
1291 |
CStringW sw1;
|
|
1292 |
TToW(*Lable, sw1);
|
|
1293 |
// Pen pen1(Color(255,0,0,0),1); //画黑线
|
|
1294 |
Pen pen2(Color(128, 128, 128, 128), 0.5); //画灰线
|
|
1295 |
|
|
1296 |
FontFamily fontfamily1(L"黑体");
|
|
1297 |
int fontsize = h1 / 60;
|
|
1298 |
if (fontsize<16) { fontsize = 16; }
|
|
1299 |
Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
|
|
1300 |
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
|
1301 |
StringFormat stringformat1;
|
|
1302 |
stringformat1.SetAlignment(StringAlignmentNear);
|
|
1303 |
stringformat1.SetLineAlignment(StringAlignmentNear);
|
|
1304 |
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 0.0f, starty + 0.0f), &stringformat1, &brush1);
|
|
1305 |
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 2.0f, starty + 2.0f), &stringformat1, &brush1);
|
|
1306 |
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 0.0f, starty + 2.0f), &stringformat1, &brush1);
|
|
1307 |
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 2.0f, starty + 0.0f), &stringformat1, &brush1);
|
|
1308 |
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 1.0f, starty + 1.0f), &stringformat1, &brush2);
|
|
1309 |
}
|
|
1310 |
if (ResultStr != NULL&&!ResultStr->IsEmpty())
|
|
1311 |
{
|
|
1312 |
CStringW sw1;
|
|
1313 |
TToW(*ResultStr, sw1);
|
|
1314 |
// Pen pen1(Color(255,0,0,0),1); //画黑线
|
|
1315 |
Pen pen2(Color(128, 128, 128, 128), 0.5); //画灰线
|
|
1316 |
SolidBrush brush3(Color(255, 0, 0, 0)); //写黑字
|
|
1317 |
SolidBrush brush4(Color(128, 0, 255, 0)); //写绿字
|
|
1318 |
|
|
1319 |
FontFamily fontfamily1(L"黑体");
|
|
1320 |
int fontsize = h1 / 4;
|
|
1321 |
if (fontsize<48) { fontsize = 48; }
|
|
1322 |
Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
|
|
1323 |
// Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
|
|
1324 |
StringFormat stringformat1;
|
|
1325 |
stringformat1.SetAlignment(StringAlignmentCenter);
|
|
1326 |
stringformat1.SetLineAlignment(StringAlignmentCenter);
|
|
1327 |
float centerx, centery;
|
|
1328 |
centerx = (rect0.right + rect0.left) / 2;
|
|
1329 |
centery = (rect0.top + rect0.bottom) / 2;
|
|
1330 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+0.0f),&stringformat1,&brush3);
|
|
1331 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+2.0f),&stringformat1,&brush3);
|
|
1332 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+2.0f),&stringformat1,&brush3);
|
|
1333 |
// gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+0.0f),&stringformat1,&brush3);
|
|
1334 |
gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(centerx + 1.0f, centery + 1.0f), &stringformat1, &brush4);
|
|
1335 |
}
|
|
1336 |
// gr1.Flush();
|
|
1337 |
ReleaseDC(DestWindow, hdc1);
|
|
1338 |
return 0;
|
|
1339 |
}
|
|
1340 |
|
|
1341 |
int LoadImageFromBuffer(void *pBuffer, ULONGLONG sizeImage, Gdiplus::Image ** ppimage1)
|
|
1342 |
{
|
|
1343 |
HGLOBAL hBuffer;
|
|
1344 |
hBuffer = GlobalAlloc(GMEM_MOVEABLE, sizeImage);
|
|
1345 |
if (hBuffer == NULL)
|
|
1346 |
{
|
|
1347 |
//s1.Format(_T("分配内存失败 \r\n")); MyLogger1.LogTxt(s1);
|
|
1348 |
return 0;
|
|
1349 |
}
|
|
1350 |
// s1.Format(_T("分配内存成功 HGlobal %x\r\n"), hBuffer); MyLogger1.LogTxt(s1);
|
|
1351 |
|
|
1352 |
LPVOID pImageData = ::GlobalLock(hBuffer);
|
|
1353 |
if (pImageData == NULL)
|
|
1354 |
{
|
|
1355 |
//s1.Format(_T("锁定内存失败\r\n")); MyLogger1.LogTxt(s1);
|
|
1356 |
::GlobalFree(hBuffer);
|
|
1357 |
return 0;
|
|
1358 |
}
|
|
1359 |
//s1.Format(_T("锁定内存成功 HGlobal %p\r\n"), pImageData); MyLogger1.LogTxt(s1);
|
|
1360 |
|
|
1361 |
memcpy(pImageData, pBuffer, sizeImage);
|
|
1362 |
::GlobalUnlock(hBuffer);
|
|
1363 |
IStream *ps = NULL;
|
|
1364 |
Gdiplus::Image *pImg = NULL;
|
|
1365 |
if (::CreateStreamOnHGlobal(hBuffer, TRUE, &ps) == S_OK)
|
|
1366 |
{
|
|
1367 |
//s1.Format(_T("创建Stream成功 \r\n")); MyLogger1.LogTxt(s1);
|
|
1368 |
pImg = Gdiplus::Image::FromStream(ps);
|
|
1369 |
if (pImg != NULL)
|
|
1370 |
{
|
|
1371 |
int w, h;
|
|
1372 |
w = pImg->GetWidth();
|
|
1373 |
h = pImg->GetHeight();
|
|
1374 |
//s1.Format(_T("创建Image成功 W %d h %d \r\n"), w, h); MyLogger1.LogTxt(s1);
|
|
1375 |
}
|
|
1376 |
//_SanUiGdiImageValid(pImg);
|
|
1377 |
*ppimage1 = pImg;
|
|
1378 |
ps->Release();
|
|
1379 |
//::GlobalFree(hBuffer);
|
|
1380 |
return 1;
|
|
1381 |
}
|
|
1382 |
return 1;
|
|
1383 |
}
|
|
1384 |
int HistoGram::MakeHistoGram(Gdiplus::Bitmap * bitmap, int startx, int starty, int width, int height)
|
|
1385 |
{
|
|
1386 |
int i,w,h;
|
|
1387 |
if (width==0) { w=bitmap->GetWidth();}
|
|
1388 |
else {w=width;}
|
|
1389 |
if (height==0) {h=bitmap->GetHeight();}
|
|
1390 |
else {h=height;}
|
|
1391 |
|
|
1392 |
totalpixels=0;
|
|
1393 |
maxRsample=0;
|
|
1394 |
maxRsampleindex=0;
|
|
1395 |
maxGsample=0;
|
|
1396 |
maxGsampleindex=0;
|
|
1397 |
maxBsample=0;
|
|
1398 |
maxBsampleindex=0;
|
|
1399 |
maxVsample=0;
|
|
1400 |
maxVsampleindex=0;
|
|
1401 |
totalRvalues=0;
|
|
1402 |
totalGvalues=0;
|
|
1403 |
totalBvalues=0;
|
|
1404 |
totalVvalues=0;
|
|
1405 |
minRvalue=255;
|
|
1406 |
maxRvalue=0;
|
|
1407 |
minGvalue=255;
|
|
1408 |
maxGvalue=0;
|
|
1409 |
minBvalue=255;
|
|
1410 |
maxBvalue=0;
|
|
1411 |
minVvalue=255;
|
|
1412 |
maxVvalue=0;
|
|
1413 |
for (i=0;i<256;i++)
|
|
1414 |
{
|
|
1415 |
Rsamples[i]=0;
|
|
1416 |
Gsamples[i]=0;
|
|
1417 |
Bsamples[i]=0;
|
|
1418 |
Vsamples[i]=0;
|
|
1419 |
}
|
|
1420 |
UINT * pixels;
|
|
1421 |
COLOR c1;
|
|
1422 |
// BYTE R,G,B;
|
|
1423 |
BYTE V;
|
|
1424 |
|
|
1425 |
Gdiplus::BitmapData bitmapData0;
|
|
1426 |
Gdiplus::Rect rect0(startx,starty,w,h);
|
|
1427 |
Gdiplus::Status GdipStatus=bitmap->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapData0);
|
|
1428 |
if (GdipStatus!=Gdiplus::Ok)
|
|
1429 |
{
|
|
1430 |
CString Errs1;
|
|
1431 |
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
|
1432 |
// SysLog(Errs1);
|
|
1433 |
return 0;
|
|
1434 |
}
|
|
1435 |
// bitmap->UnlockBits(&bitmapData0);
|
|
1436 |
// bitmap->LockBits(&rect0,ImageLockModeRead,PixelFormat32bppRGB,&bitmapData0);
|
|
1437 |
pixels=(UINT *)bitmapData0.Scan0;
|
|
1438 |
totalpixels=h*w;
|
|
1439 |
int step;step=totalpixels/1048576;
|
|
1440 |
if (step<1) {step=1;}
|
|
1441 |
step=1;
|
|
1442 |
int s=bitmapData0.Stride/4;
|
|
1443 |
// int k;
|
|
1444 |
for (i=0;i<h;i+=step)
|
|
1445 |
{
|
|
1446 |
int k=i*s;
|
|
1447 |
for (int j=0;j<width;j++)
|
|
1448 |
{
|
|
1449 |
///*
|
|
1450 |
c1.argb =pixels[k+j];
|
|
1451 |
V=int(RGBtoVI(c1.R,c1.G,c1.B));
|
|
1452 |
Rsamples[c1.R]++;
|
|
1453 |
Gsamples[c1.G]++;
|
|
1454 |
Bsamples[c1.B]++;
|
|
1455 |
Vsamples[V]++;
|
|
1456 |
}
|
|
1457 |
}
|
|
1458 |
bitmap->UnlockBits(&bitmapData0);
|
|
1459 |
///*
|
|
1460 |
totalpixels-=Vsamples[0];
|
|
1461 |
Rsamples[0]=0;
|
|
1462 |
Gsamples[0]=0;
|
|
1463 |
Bsamples[0]=0;
|
|
1464 |
Vsamples[0]=0;
|
|
1465 |
for (i=0;i<256;i++)
|
|
1466 |
{
|
|
1467 |
totalRvalues+=Rsamples[i]*i;
|
|
1468 |
totalGvalues+=Gsamples[i]*i;
|
|
1469 |
totalBvalues+=Bsamples[i]*i;
|
|
1470 |
totalVvalues+=Vsamples[i]*i;
|
|
1471 |
if (Rsamples[i]>0)
|
|
1472 |
{
|
|
1473 |
if (i<minRvalue) {minRvalue=i;}
|
|
1474 |
if (i>maxRvalue) {maxRvalue=i;}
|
|
1475 |
if (Rsamples[i]>maxRsample) {maxRsample=Rsamples[i];maxRsampleindex=i;}
|
|
1476 |
}
|
|
1477 |
if (Gsamples[i]>0)
|
|
1478 |
{
|
|
1479 |
if (i<minGvalue) {minGvalue=i;}
|
|
1480 |
if (i>maxGvalue) {maxGvalue=i;}
|
|
1481 |
if (Gsamples[i]>maxGsample) {maxGsample=Gsamples[i];maxGsampleindex=i;}
|
|
1482 |
}
|
|
1483 |
if (Bsamples[i]>0)
|
|
1484 |
{
|
|
1485 |
if (i<minBvalue) {minBvalue=i;}
|
|
1486 |
if (i>maxBvalue) {maxBvalue=i;}
|
|
1487 |
if (Bsamples[i]>maxBsample) {maxBsample=Bsamples[i];maxBsampleindex=i;}
|
|
1488 |
}
|
|
1489 |
if (Vsamples[i]>0)
|
|
1490 |
{
|
|
1491 |
if (i<minVvalue) {minVvalue=i;}
|
|
1492 |
if (i>maxVvalue) {maxVvalue=i;}
|
|
1493 |
if (Vsamples[i]>maxVsample) {maxVsample=Vsamples[i];maxVsampleindex=i;}
|
|
1494 |
}
|
|
1495 |
|
|
1496 |
}
|
|
1497 |
//*/
|
|
1498 |
|
|
1499 |
if (0==totalpixels) {totalpixels=1;}
|
|
1500 |
aveRvalue=(float)totalRvalues/totalpixels;
|
|
1501 |
aveGvalue=(float)totalGvalues/totalpixels;
|
|
1502 |
aveBvalue=(float)totalBvalues/totalpixels;
|
|
1503 |
aveVvalue=(float)totalVvalues/totalpixels;
|
|
1504 |
|
|
1505 |
if (maxRsample==0) {maxRsample=1;}
|
|
1506 |
if (maxGsample==0) {maxGsample=1;}
|
|
1507 |
if (maxBsample==0) {maxBsample=1;}
|
|
1508 |
if (maxVsample==0) {maxVsample=1;}
|
|
1509 |
|
|
1510 |
return totalpixels;
|
|
1511 |
};
|
|
1512 |
// HISTOGRAM();
|
|
1513 |
// HISTOGRAM(Bitmap * bitmap);
|
|
1514 |
// HISTOGRAM(Bitmap * bitmap)
|
|
1515 |
// {
|
|
1516 |
// MakeHistoGram(bitmap);
|
|
1517 |
// };
|
|
1518 |
int HistoGram::getRpercentvalue(float percent)
|
|
1519 |
{
|
|
1520 |
int i,j;
|
|
1521 |
j=0;
|
|
1522 |
for (i=0;i<256;i++)
|
|
1523 |
{
|
|
1524 |
j+=Rsamples[i];
|
|
1525 |
if (j>=percent*totalpixels) {break;}
|
|
1526 |
}
|
|
1527 |
return i;
|
|
1528 |
}
|
|
1529 |
|
|
1530 |
|
|
1531 |
int HistoGram::getGpercentvalue(float percent)
|
|
1532 |
{
|
|
1533 |
int i,j;
|
|
1534 |
j=0;
|
|
1535 |
for (i=0;i<256;i++)
|
|
1536 |
{
|
|
1537 |
j+=Gsamples[i];
|
|
1538 |
if (j>=percent*totalpixels) {break;}
|
|
1539 |
}
|
|
1540 |
return i;
|
|
1541 |
}
|
|
1542 |
|
|
1543 |
|
|
1544 |
int HistoGram::getBpercentvalue(float percent)
|
|
1545 |
{
|
|
1546 |
int i,j;
|
|
1547 |
j=0;
|
|
1548 |
for (i=0;i<256;i++)
|
|
1549 |
{
|
|
1550 |
j+=Bsamples[i];
|
|
1551 |
if (j>=percent*totalpixels) {break;}
|
|
1552 |
}
|
|
1553 |
return i;
|
|
1554 |
}
|
|
1555 |
|
|
1556 |
int HistoGram::getVpercentvalue(float percent)
|
|
1557 |
{
|
|
1558 |
int i,j;
|
|
1559 |
j=0;
|
|
1560 |
for (i=0;i<256;i++)
|
|
1561 |
{
|
|
1562 |
j+=Vsamples[i];
|
|
1563 |
if (j>=percent*totalpixels) {break;}
|
|
1564 |
}
|
|
1565 |
return i;
|
|
1566 |
}
|
|
1567 |
|
|
1568 |
float HistoGram::GetMostRvalue()
|
|
1569 |
{
|
|
1570 |
float r;
|
|
1571 |
int i;
|
|
1572 |
i=maxRsampleindex;
|
|
1573 |
if (i==0)
|
|
1574 |
{
|
|
1575 |
r=float(Rsamples[i]*i+Rsamples[i+1]*(i+1))/(Rsamples[i]+Rsamples[i+1]);
|
|
1576 |
return r;
|
|
1577 |
}
|
|
1578 |
if (i==255)
|
|
1579 |
{
|
|
1580 |
r=float(Rsamples[i-1]*(i-1)+Rsamples[i]*(i))/(Rsamples[i-1]+Rsamples[i]);
|
|
1581 |
return r;
|
|
1582 |
}
|
|
1583 |
if (Rsamples[i-1]>Rsamples[i+1])
|
|
1584 |
{
|
|
1585 |
int sample1,samplemax,sample2;
|
|
1586 |
sample1=Rsamples[i-1];
|
|
1587 |
samplemax=Rsamples[i];
|
|
1588 |
sample2=Rsamples[i+1];
|
|
1589 |
r=float(i)-float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
|
1590 |
}
|
|
1591 |
else
|
|
1592 |
{
|
|
1593 |
int sample1,samplemax,sample2;
|
|
1594 |
sample2=Rsamples[i-1];
|
|
1595 |
samplemax=Rsamples[i];
|
|
1596 |
sample1=Rsamples[i+1];
|
|
1597 |
r=float(i)+float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
|
1598 |
|
|
1599 |
}
|
|
1600 |
//r=double(Rsamples[i-1]*(i-1)+Rsamples[i]*(i)+Rsamples[i+1]*(i+1))/(Rsamples[i-1]+Rsamples[i]+Rsamples[i+1]);
|
|
1601 |
return r;
|
|
1602 |
}
|
|
1603 |
float HistoGram::GetMostGvalue()
|
|
1604 |
{
|
|
1605 |
float g;
|
|
1606 |
int i;
|
|
1607 |
i=maxGsampleindex;
|
|
1608 |
if (i==0)
|
|
1609 |
{
|
|
1610 |
g=float(Gsamples[i]*i+Gsamples[i+1]*(i+1))/(Gsamples[i]+Gsamples[i+1]);
|
|
1611 |
return g;
|
|
1612 |
}
|
|
1613 |
if (i==255)
|
|
1614 |
{
|
|
1615 |
g=float(Gsamples[i-1]*(i-1)+Gsamples[i]*(i))/(Gsamples[i-1]+Gsamples[i]);
|
|
1616 |
return g;
|
|
1617 |
}
|
|
1618 |
if (Gsamples[i-1]>Gsamples[i+1])
|
|
1619 |
{
|
|
1620 |
int sample1,samplemax,sample2;
|
|
1621 |
sample1=Gsamples[i-1];
|
|
1622 |
samplemax=Gsamples[i];
|
|
1623 |
sample2=Gsamples[i+1];
|
|
1624 |
g=float(i)-float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
|
1625 |
}
|
|
1626 |
else
|
|
1627 |
{
|
|
1628 |
int sample1,samplemax,sample2;
|
|
1629 |
sample2=Gsamples[i-1];
|
|
1630 |
samplemax=Gsamples[i];
|
|
1631 |
sample1=Gsamples[i+1];
|
|
1632 |
g=float(i)+float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
|
1633 |
|
|
1634 |
}
|
|
1635 |
// g=double(Gsamples[i-1]*(i-1)+Gsamples[i]*(i)+Gsamples[i+1]*(i+1))/(Gsamples[i-1]+Gsamples[i]+Gsamples[i+1]);
|
|
1636 |
return g;
|
|
1637 |
}
|
|
1638 |
float HistoGram::GetMostBvalue()
|
|
1639 |
{
|
|
1640 |
float b;
|
|
1641 |
int i;
|
|
1642 |
i=maxBsampleindex;
|
|
1643 |
if (i==0)
|
|
1644 |
{
|
|
1645 |
b=float(Bsamples[i]*i+Bsamples[i+1]*(i+1))/(Bsamples[i]+Bsamples[i+1]);
|
|
1646 |
return b;
|
|
1647 |
}
|
|
1648 |
if (i==255)
|
|
1649 |
{
|
|
1650 |
b=float(Bsamples[i-1]*(i-1)+Bsamples[i]*(i))/(Bsamples[i-1]+Bsamples[i]);
|
|
1651 |
return b;
|
|
1652 |
}
|
|
1653 |
if (Bsamples[i-1]>Bsamples[i+1])
|
|
1654 |
{
|
|
1655 |
int sample1,samplemax,sample2;
|
|
1656 |
sample1=Bsamples[i-1];
|
|
1657 |
samplemax=Bsamples[i];
|
|
1658 |
sample2=Bsamples[i+1];
|
|
1659 |
b=float(i)-float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
|
1660 |
}
|
|
1661 |
else
|
|
1662 |
{
|
|
1663 |
int sample1,samplemax,sample2;
|
|
1664 |
sample2=Bsamples[i-1];
|
|
1665 |
samplemax=Bsamples[i];
|
|
1666 |
sample1=Bsamples[i+1];
|
|
1667 |
b=float(i)+float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
|
|
1668 |
|
|
1669 |
}
|
|
1670 |
|
|
1671 |
b=float(Bsamples[i-1]*(i-1)+Bsamples[i]*(i)+Bsamples[i+1]*(i+1))/(Bsamples[i-1]+Bsamples[i]+Bsamples[i+1]);
|
|
1672 |
return b;
|
|
1673 |
}
|
|
1674 |
|
|
1675 |
int QuadRectTransForm(Gdiplus::Bitmap* bitmapsrc,POINT srcpt[4],Gdiplus::Bitmap * bitmapdest,Gdiplus::Rect destrect)
|
|
1676 |
{
|
|
1677 |
Gdiplus::PointF pt[4];
|
|
1678 |
for (int i=0;i<4;i++)
|
|
1679 |
{
|
|
1680 |
pt[i].X=float(srcpt[i].x);pt[i].Y=float(srcpt[i].y);
|
|
1681 |
}
|
|
1682 |
return QuadRectTransForm(bitmapsrc,pt,bitmapdest,destrect);
|
|
1683 |
}
|
|
1684 |
int QuadRectTransForm(Gdiplus::Bitmap* bitmapsrc,Gdiplus::Point srcpt[4],Gdiplus::Bitmap * bitmapdest,Gdiplus::Rect destrect)
|
|
1685 |
{
|
|
1686 |
Gdiplus::PointF pt[4];
|
|
1687 |
for (int i=0;i<4;i++)
|
|
1688 |
{
|
|
1689 |
pt[i].X=float(srcpt[i].X);pt[i].Y=float(srcpt[i].X);
|
|
1690 |
}
|
|
1691 |
return QuadRectTransForm(bitmapsrc,pt,bitmapdest,destrect);
|
|
1692 |
return 1;
|
|
1693 |
}
|
|
1694 |
|
|
1695 |
UINT __cdecl TransFormThread(LPVOID pParam)
|
|
1696 |
{
|
|
1697 |
TransFormThreadDataStruct * mydata=(TransFormThreadDataStruct *)pParam;
|
|
1698 |
int w,h;
|
|
1699 |
w=mydata->destrect.Width;
|
|
1700 |
h=mydata->destrect.Height;
|
|
1701 |
|
|
1702 |
Gdiplus::PointF startpt,endpt,curpt;
|
|
1703 |
|
|
1704 |
Gdiplus::PointF leftdelta,rightDelta;
|
|
1705 |
Gdiplus::PointF leftstart,rightstart;
|
|
1706 |
Gdiplus::PointF curstart,curdelta;
|
|
1707 |
int i,j,k,l;
|
|
1708 |
|
|
1709 |
int curx,cury; //最临近的像素? 左上角的像素
|
|
1710 |
COLORf c1f;
|
|
1711 |
COLOR c1;
|
|
1712 |
COLOR src[2][2];
|
|
1713 |
float jitx,jity,remainx,remainy;
|
|
1714 |
UINT * myDestPixels=mydata->destpixels;
|
|
1715 |
int myno=mydata->ThreadNo;
|
|
1716 |
double time1=GetTickCountmS();
|
|
1717 |
for (i=mydata->starth;i<mydata->endh;i++)
|
|
1718 |
{
|
|
1719 |
|
|
1720 |
startpt.X=(mydata->srcpt[0].X*(h-i)+mydata->srcpt[3].X*(i))/(float)h;
|
|
1721 |
startpt.Y=(mydata->srcpt[0].Y*(h-i)+mydata->srcpt[3].Y*(i))/(float)h;
|
|
1722 |
|
|
1723 |
endpt.X=(mydata->srcpt[1].X*(h-i)+mydata->srcpt[2].X*(i))/(float)h;
|
|
1724 |
endpt.Y=(mydata->srcpt[1].Y*(h-i)+mydata->srcpt[2].Y*(i))/(float)h;
|
|
1725 |
|
|
1726 |
|
|
1727 |
l=i*mydata->deststride;
|
|
1728 |
for (j=0;j<w;j++)
|
|
1729 |
{
|
|
1730 |
curpt.X=(startpt.X*(w-j)+endpt.X*(j))/w;
|
|
1731 |
curpt.Y=(startpt.Y*(w-j)+endpt.Y*(j))/w;
|
|
1732 |
curx=int(curpt.X); cury=int(curpt.Y);
|
|
1733 |
if (curx<0||curx>=mydata->srcw-1) {continue;}
|
|
1734 |
if (cury<0||cury>=mydata->srch-1) {continue;}
|
|
1735 |
jitx=curpt.X-curx; jity=curpt.Y-cury; //双线性插值
|
|
1736 |
remainx=1.0f-jitx; remainy=1.0f-jity;
|
|
1737 |
double remainxremainy=remainx*remainy;
|
|
1738 |
double jitxremainy=jitx*remainy;
|
|
1739 |
double remainxjity=remainx*jity;
|
|
1740 |
double jitxjity=jitx*jity;
|
|
1741 |
k=cury*mydata->srcstride;
|
|
1742 |
src[0][0].argb = mydata->srcpixels[k+curx];
|
|
1743 |
src[0][1].argb = mydata->srcpixels[k+curx+1];
|
|
1744 |
src[1][0].argb = mydata->srcpixels[k+mydata->srcstride+curx];
|
|
1745 |
src[1][1].argb = mydata->srcpixels[k+mydata->srcstride+curx+1];
|
|
1746 |
|
|
1747 |
c1f.R=float( src[0][0].R*remainxremainy+src[0][1].R*jitxremainy+src[1][0].R*remainxjity+src[1][1].R*jitxjity);
|
|
1748 |
c1f.G=float( src[0][0].G*remainxremainy+src[0][1].G*jitxremainy+src[1][0].G*remainxjity+src[1][1].G*jitxjity);
|
|
1749 |
c1f.B=float( src[0][0].B*remainxremainy+src[0][1].B*jitxremainy+src[1][0].B*remainxjity+src[1][1].B*jitxjity);
|
|
1750 |
|
|
1751 |
c1.R=int(c1f.R); c1.G=int(c1f.G); c1.B=int(c1f.B);c1.A=255;
|
|
1752 |
myDestPixels[l+j]=c1.argb;
|
|
1753 |
|
|
1754 |
//srcpixels[cury*srcstride+curx]; //最邻近像素取值
|
|
1755 |
}
|
|
1756 |
}
|
|
1757 |
double time2=GetTickCountmS();
|
|
1758 |
double time3=time2-time1;
|
|
1759 |
mydata->Done=1;
|
|
1760 |
return 1000+myno;
|
|
1761 |
};
|
|
1762 |
int QuadRectTransForm(Gdiplus::Bitmap* bitmapsrc,Gdiplus::PointF srcpt[4],Gdiplus::Bitmap * bitmapdest,Gdiplus::Rect destrect)
|
|
1763 |
{
|
|
1764 |
Gdiplus::BitmapData bitmapdatasrc;
|
|
1765 |
Gdiplus::BitmapData bitmapdatadest;
|
|
1766 |
int srcw,srch;
|
|
1767 |
if (bitmapsrc==NULL) {return -1;}
|
|
1768 |
srcw=bitmapsrc->GetWidth();
|
|
1769 |
srch=bitmapsrc->GetHeight();
|
|
1770 |
Gdiplus::Rect rect1(0,0,srcw,srch);
|
|
1771 |
Gdiplus::Status sta1,sta2;
|
|
1772 |
sta1=bitmapsrc->LockBits(&rect1,Gdiplus::ImageLockModeRead,PixelFormat32bppARGB,&bitmapdatasrc);
|
|
1773 |
if (sta1!=Gdiplus::Ok)
|
|
1774 |
{
|
|
1775 |
return -1;
|
|
1776 |
}
|
|
1777 |
sta2=bitmapdest->LockBits(&destrect,Gdiplus::ImageLockModeWrite,PixelFormat32bppARGB,&bitmapdatadest);
|
|
1778 |
if (sta2!=Gdiplus::Ok)
|
|
1779 |
{
|
|
1780 |
return -1;
|
|
1781 |
}
|
|
1782 |
UINT *srcpixels=(UINT *)bitmapdatasrc.Scan0;
|
|
1783 |
int srcstride=bitmapdatasrc.Stride/4;;
|
|
1784 |
UINT *destpixels=(UINT *)bitmapdatadest.Scan0;
|
|
1785 |
int deststride=bitmapdatadest.Stride/4;
|
|
1786 |
int w,h;
|
|
1787 |
w=destrect.Width;
|
|
1788 |
h=destrect.Height;
|
|
1789 |
#define ThreadCount 2
|
|
1790 |
TransFormThreadDataStruct TransFromThreadData[ThreadCount];
|
|
1791 |
for (int i=0;i<ThreadCount;i++)
|
|
1792 |
{
|
|
1793 |
TransFromThreadData[i].ThreadNo=i;
|
|
1794 |
TransFromThreadData[i].Done=0;
|
|
1795 |
TransFromThreadData[i].srcpixels=srcpixels;
|
|
1796 |
TransFromThreadData[i].srcstride=srcstride;
|
|
1797 |
TransFromThreadData[i].destpixels=destpixels;
|
|
1798 |
TransFromThreadData[i].deststride=deststride;
|
|
1799 |
TransFromThreadData[i].srcw=srcw;
|
|
1800 |
TransFromThreadData[i].srch=srch;
|
|
1801 |
TransFromThreadData[i].srcpt[0]=srcpt[0];
|
|
1802 |
TransFromThreadData[i].srcpt[1]=srcpt[1];
|
|
1803 |
TransFromThreadData[i].srcpt[2]=srcpt[2];
|
|
1804 |
TransFromThreadData[i].srcpt[3]=srcpt[3];
|
|
1805 |
TransFromThreadData[i].destrect=destrect;
|
|
1806 |
TransFromThreadData[i].starth=i*h/ThreadCount;
|
|
1807 |
TransFromThreadData[i].endh=(i+1)*h/ThreadCount;
|
|
1808 |
}
|
|
1809 |
|
|
1810 |
CWinThread * threads[ThreadCount];
|
|
1811 |
HANDLE hthreads[ThreadCount];
|
|
1812 |
CString s1;
|
|
1813 |
DWORD dwerr;
|
|
1814 |
// CWinThread thread1(TransFormThread,(LPVOID)(&TransFromThreadData[0]));
|
|
1815 |
// CWinThread thread2(TransFormThread,(LPVOID)(&TransFromThreadData[0]));
|
|
1816 |
for (int i=0;i<ThreadCount;i++)
|
|
1817 |
{
|
|
1818 |
threads[i]=AfxBeginThread(TransFormThread,(LPVOID)(&TransFromThreadData[i]),0,8192);
|
|
1819 |
if (threads[i]!=NULL)
|
|
1820 |
{
|
|
1821 |
hthreads[i]=threads[i]->m_hThread;
|
|
1822 |
}
|
|
1823 |
else
|
|
1824 |
{
|
|
1825 |
dwerr=GetLastError();
|
|
1826 |
s1.Format(_T("BeginThread %d fail %d \r\n"),i,dwerr);
|
|
1827 |
// SysLog(s1);
|
|
1828 |
}
|
|
1829 |
}
|
|
1830 |
// DWORD iRet;
|
|
1831 |
// iRet=WaitForMultipleObjects(ThreadCount,hthreads,true,3000);
|
|
1832 |
|
|
1833 |
while(1)
|
|
1834 |
{
|
|
1835 |
int jumpout=1;
|
|
1836 |
for (int i=0;i<ThreadCount;i++)
|
|
1837 |
{
|
|
1838 |
if (TransFromThreadData[i].Done==0) jumpout=0;
|
|
1839 |
}
|
|
1840 |
if (jumpout) break;
|
|
1841 |
Sleep(10);
|
|
1842 |
};
|
|
1843 |
|
|
1844 |
/*
|
|
1845 |
PointF startpt,endpt,curpt;
|
|
1846 |
|
|
1847 |
PointF leftdelta,rightDelta;
|
|
1848 |
PointF leftstart,rightstart;
|
|
1849 |
PointF curstart,curdelta;
|
|
1850 |
int i,j;//,k,l;
|
|
1851 |
|
|
1852 |
int curx,cury; //最临近的像素? 左上角的像素
|
|
1853 |
COLORf c1f;
|
|
1854 |
COLOR c1;
|
|
1855 |
COLOR src[2][2];
|
|
1856 |
float jitx,jity,remainx,remainy;
|
|
1857 |
|
|
1858 |
|
|
1859 |
|
|
1860 |
for (i=0;i<h;i++)
|
|
1861 |
{
|
|
1862 |
|
|
1863 |
startpt.X=(srcpt[0].X*(h-i)+srcpt[3].X*(i))/(float)h;
|
|
1864 |
startpt.Y=(srcpt[0].Y*(h-i)+srcpt[3].Y*(i))/(float)h;
|
|
1865 |
|
|
1866 |
endpt.X=(srcpt[1].X*(h-i)+srcpt[2].X*(i))/(float)h;
|
|
1867 |
endpt.Y=(srcpt[1].Y*(h-i)+srcpt[2].Y*(i))/(float)h;
|
|
1868 |
|
|
1869 |
|
|
1870 |
for (j=0;j<w;j++)
|
|
1871 |
{
|
|
1872 |
curpt.X=(startpt.X*(w-j)+endpt.X*(j))/w;
|
|
1873 |
curpt.Y=(startpt.Y*(w-j)+endpt.Y*(j))/w;
|
|
1874 |
curx=int(curpt.X); cury=int(curpt.Y);
|
|
1875 |
if (curx<0||curx>=srcw-1) {continue;}
|
|
1876 |
if (cury<0||cury>=srch-1) {continue;}
|
|
1877 |
jitx=curpt.X-curx; jity=curpt.Y-cury; //双线性插值
|
|
1878 |
remainx=1.0f-jitx; remainy=1.0f-jity;
|
|
1879 |
double remainxremainy=remainx*remainy;
|
|
1880 |
double jitxremainy=jitx*remainy;
|
|
1881 |
double remainxjity=remainx*jity;
|
|
1882 |
double jitxjity=jitx*jity;
|
|
1883 |
src[0][0].argb = srcpixels[cury*srcstride+curx];
|
|
1884 |
src[0][1].argb = srcpixels[cury*srcstride+curx+1];
|
|
1885 |
src[1][0].argb = srcpixels[(cury+1)*srcstride+curx];
|
|
1886 |
src[1][1].argb = srcpixels[(cury+1)*srcstride+curx+1];
|
|
1887 |
//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;
|
|
1888 |
//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;
|
|
1889 |
//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;
|
|
1890 |
c1f.R= src[0][0].R*remainxremainy+src[0][1].R*jitxremainy+src[1][0].R*remainxjity+src[1][1].R*jitxjity;
|
|
1891 |
c1f.G= src[0][0].G*remainxremainy+src[0][1].G*jitxremainy+src[1][0].G*remainxjity+src[1][1].G*jitxjity;
|
|
1892 |
c1f.B= src[0][0].B*remainxremainy+src[0][1].B*jitxremainy+src[1][0].B*remainxjity+src[1][1].B*jitxjity;
|
|
1893 |
|
|
1894 |
c1.R=int(c1f.R); c1.G=int(c1f.G); c1.B=int(c1f.B);c1.A=255;
|
|
1895 |
destpixels[i*deststride+j]=c1.argb;
|
|
1896 |
|
|
1897 |
//srcpixels[cury*srcstride+curx]; //最邻近像素取值
|
|
1898 |
}
|
|
1899 |
}
|
|
1900 |
*/
|
|
1901 |
bitmapdest->UnlockBits(&bitmapdatadest);
|
|
1902 |
bitmapsrc->UnlockBits(&bitmapdatasrc);
|
|
1903 |
return 1;
|
|
1904 |
}
|
|
1905 |
|
|
1906 |
|
|
1907 |
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
|
|
1908 |
{
|
|
1909 |
UINT num = 0; // number of image encoders
|
|
1910 |
UINT size = 0; // size of the image encoder array in bytes
|
|
1911 |
|
|
1912 |
Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
|
|
1913 |
|
|
1914 |
Gdiplus::GetImageEncodersSize(&num, &size);
|
|
1915 |
if(size == 0)
|
|
1916 |
return -1; // Failure
|
|
1917 |
|
|
1918 |
pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
|
|
1919 |
if(pImageCodecInfo == NULL)
|
|
1920 |
return -1; // Failure
|
|
1921 |
|
|
1922 |
Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);
|
|
1923 |
|
|
1924 |
for(UINT j = 0; j < num; ++j)
|
|
1925 |
{
|
|
1926 |
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
|
|
1927 |
{
|
|
1928 |
*pClsid = pImageCodecInfo[j].Clsid;
|
|
1929 |
free(pImageCodecInfo);
|
|
1930 |
return j; // Success
|
|
1931 |
}
|
|
1932 |
}
|
|
1933 |
|
|
1934 |
free(pImageCodecInfo);
|
|
1935 |
return -1; // Failure
|
|
1936 |
}
|
|
1937 |
int SaveGdiPImageAsFile(Gdiplus::Bitmap * bitmap1, CString sFileName, double Ratio,int Quality)
|
|
1938 |
{
|
|
1939 |
|
|
1940 |
// double tick0=GetTickCountmS();
|
|
1941 |
CString s1;
|
|
1942 |
int w,h;
|
|
1943 |
if (Ratio==0) {Ratio=1;}
|
|
1944 |
if (bitmap1==NULL)
|
|
1945 |
{
|
|
1946 |
s1.Format(_T("源图像为空,不能保存\r\n"));
|
|
1947 |
// SysLog(s1);
|
|
1948 |
return 0;
|
|
1949 |
}
|
|
1950 |
if (bitmap1->GetWidth()==0||bitmap1->GetHeight()==0)
|
|
1951 |
{
|
|
1952 |
s1.Format(_T("源图像为空,不能保存\r\n"));
|
|
1953 |
// SysLog(s1);
|
|
1954 |
return 0;
|
|
1955 |
}
|
|
1956 |
CString sFilePath;
|
|
1957 |
sFilePath=sFileName.Left(sFileName.ReverseFind(_T('\\')));
|
|
1958 |
//检查是否有可用的磁盘空间
|
|
1959 |
ULARGE_INTEGER luse;
|
|
1960 |
ULARGE_INTEGER ltotal;
|
|
1961 |
ULARGE_INTEGER lfree;
|
|
1962 |
|
|
1963 |
double fuse,ftotal,ffree;
|
|
1964 |
GetDiskFreeSpaceEx(sFilePath,&luse,<otal,&lfree);
|
|
1965 |
fuse=luse.QuadPart/1024.0/1024.0/1024.0;
|
|
1966 |
ftotal=ltotal.QuadPart/1048576.0/1024.0;
|
|
1967 |
ffree=lfree.QuadPart/1048576.0/1024.0;
|
|
1968 |
if (fuse<2.0) {return 0;} //如果可用空间小于2G,那么不存储文件。
|
|
1969 |
//创建目录
|
|
1970 |
SHCreateDirectoryEx(NULL,sFilePath,NULL);
|
|
1971 |
//创建BMP文件
|
|
1972 |
w=int(bitmap1->GetWidth()*Ratio+0.5);
|
|
1973 |
h=int(bitmap1->GetHeight()*Ratio+0.5);
|
|
1974 |
Gdiplus::Bitmap bitmapsave(w,h,PixelFormat24bppRGB);
|
|
1975 |
Gdiplus::Graphics graphic3(&bitmapsave);
|
|
1976 |
graphic3.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
|
|
1977 |
graphic3.DrawImage(bitmap1,Gdiplus::Rect(0,0,w,h),0,0,bitmap1->GetWidth(),bitmap1->GetHeight(),Gdiplus::UnitPixel); //比例缩放
|
|
1978 |
CLSID bmpClsid;
|
|
1979 |
CLSID gifClsid;
|
|
1980 |
CLSID pngClsid;
|
|
1981 |
CLSID jpegClsid;
|
|
1982 |
CLSID tifClsid;
|
|
1983 |
GetEncoderClsid(L"image/bmp", &bmpClsid);
|
|
1984 |
GetEncoderClsid(L"image/jpeg", &jpegClsid);
|
|
1985 |
GetEncoderClsid(L"image/gif", &gifClsid);
|
|
1986 |
GetEncoderClsid(L"image/tiff", &tifClsid);
|
|
1987 |
GetEncoderClsid(L"image/png", &pngClsid);
|
|
1988 |
// int i,j;
|
|
1989 |
// CString s1;
|
|
1990 |
CStringW sw1;
|
|
1991 |
CString s2;
|
|
1992 |
//FilePathName=Prsfilepath+_T("\\")+savedfilename;
|
|
1993 |
s1=sFileName;
|
|
1994 |
|
|
1995 |
// ::SysLog(s1);
|
|
1996 |
// wcscpy_s(wbuf1,1000,ToWChar(s1.GetBuffer(100)));
|
|
1997 |
ULONG picquality=Quality;
|
|
1998 |
Gdiplus::EncoderParameters * pparas1 = (Gdiplus::EncoderParameters *) new byte[sizeof(EncoderParameters) + sizeof(EncoderParameter)];
|
|
1999 |
|
|
2000 |
pparas1->Count=1;
|
|
2001 |
pparas1->Parameter[0].Guid=Gdiplus::EncoderQuality;
|
|
2002 |
pparas1->Parameter[0].Type=Gdiplus::EncoderParameterValueTypeLong;
|
|
2003 |
pparas1->Parameter[0].NumberOfValues=1;
|
|
2004 |
pparas1->Parameter[0].Value=&picquality;
|
|
2005 |
|
|
2006 |
//pparas1->Count = 2;
|
|
2007 |
//ULONG value2 = EncoderValueCompressionLZW;
|
|
2008 |
//pparas1->Parameter[1].Guid = Gdiplus::EncoderCompression;
|
|
2009 |
//pparas1->Parameter[1].Type = Gdiplus::EncoderParameterValueTypeLong;
|
|
2010 |
//pparas1->Parameter[1].NumberOfValues = 1;
|
|
2011 |
//pparas1->Parameter[1].Value = &value2;
|
|
2012 |
|
|
2013 |
#ifdef UNICODE
|
|
2014 |
sw1.Format(L"%s",s1);
|
|
2015 |
#else
|
|
2016 |
WCHAR wbuf1[1000];
|
|
2017 |
wcscpy_s(wbuf1,1000,ToWChar(s1.GetBuffer(100)));
|
|
2018 |
sw1.Format(L"%s",wbuf1);
|
|
2019 |
#endif
|
|
2020 |
if (sw1.Find(L".BMP") > 0)
|
|
2021 |
{
|
|
2022 |
bitmapsave.Save(sw1, &bmpClsid, pparas1);
|
|
2023 |
}
|
|
2024 |
else if (sw1.Find(L".JPG") > 0)
|
|
2025 |
{
|
|
2026 |
bitmapsave.Save(sw1, &jpegClsid, pparas1);
|
|
2027 |
}
|
|
2028 |
else if (sw1.Find(L".GIF") > 0)
|
|
2029 |
{
|
|
2030 |
bitmapsave.Save(sw1, &gifClsid, pparas1);
|
|
2031 |
}
|
|
2032 |
else if (sw1.Find(L".TIF") > 0)
|
|
2033 |
{
|
|
2034 |
bitmapsave.Save(sw1, &tifClsid, pparas1);
|
|
2035 |
}
|
|
2036 |
else if (sw1.Find(L".PNG") > 0)
|
|
2037 |
{
|
|
2038 |
bitmapsave.Save(sw1, &pngClsid, pparas1);
|
|
2039 |
}
|
|
2040 |
else
|
|
2041 |
{
|
|
2042 |
bitmapsave.Save(sw1, &bmpClsid, pparas1);
|
|
2043 |
}
|
|
2044 |
// double tick1=GetTickCountmS();
|
|
2045 |
delete[] pparas1;
|
|
2046 |
return 1;
|
|
2047 |
|
|
2048 |
}
|
|
2049 |
int SaveGdiPImageAsBuffer(Gdiplus::Image * image1, void ** ppBuffer, ULONGLONG *psizeImage, double Ratio, int Quality)
|
|
2050 |
{
|
|
2051 |
|
|
2052 |
// double tick0=GetTickCountmS();
|
|
2053 |
CString s1;
|
|
2054 |
int w, h;
|
|
2055 |
if (Ratio == 0) { Ratio = 1; }
|
|
2056 |
if (image1 == NULL)
|
|
2057 |
{
|
|
2058 |
s1.Format(_T("源图像为空,不能保存\r\n"));
|
|
2059 |
// SysLog(s1);
|
|
2060 |
return 0;
|
|
2061 |
}
|
|
2062 |
|
|
2063 |
w = int(image1->GetWidth()*Ratio + 0.5);
|
|
2064 |
h = int(image1->GetHeight()*Ratio + 0.5);
|
|
2065 |
Gdiplus::Bitmap bitmapsave(w, h, PixelFormat24bppRGB);
|
|
2066 |
Gdiplus::Graphics graphic3(&bitmapsave);
|
|
2067 |
graphic3.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
|
|
2068 |
graphic3.DrawImage(image1, Gdiplus::Rect(0, 0, w, h), 0, 0, image1->GetWidth(), image1->GetHeight(), Gdiplus::UnitPixel); //比例缩放
|
|
2069 |
CLSID bmpClsid;
|
|
2070 |
CLSID gifClsid;
|
|
2071 |
CLSID pngClsid;
|
|
2072 |
CLSID jpegClsid;
|
|
2073 |
CLSID tifClsid;
|
|
2074 |
GetEncoderClsid(L"image/bmp", &bmpClsid);
|
|
2075 |
GetEncoderClsid(L"image/jpeg", &jpegClsid);
|
|
2076 |
GetEncoderClsid(L"image/gif", &gifClsid);
|
|
2077 |
GetEncoderClsid(L"image/tiff", &tifClsid);
|
|
2078 |
GetEncoderClsid(L"image/png", &pngClsid);
|
|
2079 |
// int i,j;
|
|
2080 |
// CString s1;
|
|
2081 |
CStringW sw1;
|
|
2082 |
CString s2;
|
|
2083 |
//FilePathName=Prsfilepath+_T("\\")+savedfilename;
|
|
2084 |
|
|
2085 |
// ::SysLog(s1);
|
|
2086 |
// wcscpy_s(wbuf1,1000,ToWChar(s1.GetBuffer(100)));
|
|
2087 |
ULONG picquality = Quality;
|
|
2088 |
Gdiplus::EncoderParameters paras1;
|
|
2089 |
|
|
2090 |
paras1.Count = 1;
|
|
2091 |
paras1.Parameter[0].Guid = Gdiplus::EncoderQuality;
|
|
2092 |
paras1.Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;
|
|
2093 |
paras1.Parameter[0].NumberOfValues = 1;
|
|
2094 |
paras1.Parameter[0].Value = &picquality;
|
|
2095 |
|
|
2096 |
IStream *ps2;
|
|
2097 |
CreateStreamOnHGlobal(NULL, TRUE, &ps2);
|
|
2098 |
bitmapsave.Save(ps2, &jpegClsid, ¶s1);
|
|
2099 |
LARGE_INTEGER dlibMove;
|
|
2100 |
dlibMove.QuadPart = 0;
|
|
2101 |
ULARGE_INTEGER libNewPosition;
|
|
2102 |
ps2->Seek(dlibMove, STREAM_SEEK_END, &libNewPosition);
|
|
2103 |
int sizeImage;
|
|
2104 |
sizeImage = libNewPosition.QuadPart;
|
|
2105 |
ps2->Seek(dlibMove, STREAM_SEEK_SET, &libNewPosition);
|
|
2106 |
void * pBuffer = new char[sizeImage];
|
|
2107 |
DWORD dwRead;
|
|
2108 |
ps2->Read(pBuffer, sizeImage, &dwRead);
|
|
2109 |
*psizeImage = sizeImage;
|
|
2110 |
*ppBuffer = pBuffer;
|
|
2111 |
|
|
2112 |
return 1;
|
|
2113 |
|
|
2114 |
}
|
|
2115 |
|
|
2116 |
HSI RGBToHSI(COLOR c1)
|
|
2117 |
{
|
|
2118 |
float nMax,nMin,ndelMax;
|
|
2119 |
float ndelR,ndelG,ndelB;
|
|
2120 |
float nH,nS,nV;
|
|
2121 |
float nR,nB,nG;
|
|
2122 |
HSI hsb2;
|
|
2123 |
nR=c1.R/255.0f;
|
|
2124 |
nG=c1.G/255.0f;
|
|
2125 |
nB=c1.B/255.0f;
|
|
2126 |
nMax=max(nR,max(nG,nB));
|
|
2127 |
nMin=min(nR,min(nG,nB));
|
|
2128 |
ndelMax=nMax-nMin;
|
|
2129 |
nV=nMax;
|
|
2130 |
if (ndelMax==0) {nS=0;nH=0;} //最大值与最小值相等,纯色。
|
|
2131 |
else
|
|
2132 |
{
|
|
2133 |
nS=ndelMax/nMax;
|
|
2134 |
ndelR = (((nMax - nR) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
|
2135 |
ndelG = (((nMax - nG) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
|
2136 |
ndelB = (((nMax - nB) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
|
2137 |
if (nR==nMax)
|
|
2138 |
{
|
|
2139 |
nH = ndelB - ndelG;
|
|
2140 |
}
|
|
2141 |
else if (nG==nMax)
|
|
2142 |
{
|
|
2143 |
nH = (1.0f / 3) + ndelR - ndelB;
|
|
2144 |
|
|
2145 |
}
|
|
2146 |
else if (nB==nMax)
|
|
2147 |
{
|
|
2148 |
nH = (2.0f / 3) + ndelG - ndelR;
|
|
2149 |
}
|
|
2150 |
if (nH<0) {nH+=1;}
|
|
2151 |
if (nH>1) {nH-=1;}
|
|
2152 |
|
|
2153 |
}
|
|
2154 |
hsb2.H =(nH*240);
|
|
2155 |
hsb2.S =(nS*240);
|
|
2156 |
hsb2.I =(nV*240);
|
|
2157 |
|
|
2158 |
return hsb2 ;
|
|
2159 |
}
|
|
2160 |
/* RGB?-----------?Lab
|
|
2161 |
(各分量数值范围:R/G/B: 0~255; L: 0~100, a/b:0~255)
|
|
2162 |
|
|
2163 |
RGB---?Lab:
|
|
2164 |
X = 0.412453*R + 0.357580*G + 0.180423*B;
|
|
2165 |
Y = 0.212671*R + 0.715160*G + 0.072169*B;
|
|
2166 |
Z = 0.019334*R + 0.119193*G + 0.950227*B;
|
|
2167 |
|
|
2168 |
X = X/(255*0.950456);
|
|
2169 |
Y = Y/255;
|
|
2170 |
Z = Z/(255*1.088754);
|
|
2171 |
如果Y > 0.008856,则 :
|
|
2172 |
fY = Y^(1/3);
|
|
2173 |
fX = X^(1/3);
|
|
2174 |
fZ = Z^(1/3);
|
|
2175 |
L= 116*fY - 16;
|
|
2176 |
如果Y < 0.008856,则
|
|
2177 |
fY = 7.787*Y + 16/116;
|
|
2178 |
fX = 7.787*X + 16/116;
|
|
2179 |
fZ = 7.787*Z + 16/116;
|
|
2180 |
L= 903.3*Y;
|
|
2181 |
a = 500.0*(fX - fY) +128;
|
|
2182 |
b = 200.0*(fY - fZ) +128;
|
|
2183 |
|
|
2184 |
Lab---?RGB:
|
|
2185 |
a = a-128;
|
|
2186 |
b = b-128;
|
|
2187 |
fY = ((L + 16) / 116))^3;
|
|
2188 |
如果fY < 0.008856,则fY = L / 903.3;
|
|
2189 |
Y = fY;
|
|
2190 |
如果fY > 0.008856,则fY = fY^(1/3);
|
|
2191 |
如果fY < 0.008856,则fY = 7.787 * fY + 16/116;
|
|
2192 |
|
|
2193 |
fX = a / 500 + fY;
|
|
2194 |
如果fX > 0.206893,则X = fX^(1/3);
|
|
2195 |
如果fX < 0.206893,则X = (fX - 16/116) / 7.787;
|
|
2196 |
|
|
2197 |
fZ = fY - b /200;
|
|
2198 |
如果fZ > 0.206893,则Z = fZ^(1/3);
|
|
2199 |
如果fX < 0.206893,则Z = (fZ - 16/116) / 7.787;
|
|
2200 |
|
|
2201 |
X = X * 0.950456 * 255;
|
|
2202 |
Y = Y *255;
|
|
2203 |
Z = Z * 1.088754 * 255;
|
|
2204 |
R = 3.240479*X - 1.537150*Y - 0.498535*Z
|
|
2205 |
G =-0.969256*X + 1.875992*Y + 0.041556*Z;
|
|
2206 |
B = 0.055648*X - 0.204043*Y + 1.057311*Z;
|
|
2207 |
|
|
2208 |
*/
|
|
2209 |
|
|
2210 |
/*
|
|
2211 |
从RGB到Lab色彩空间的转换
|
|
2212 |
2008年七月27日 星期日, 03:35 - 键盘生涯 / Programming
|
|
2213 |
虽然若干年前就看过了关于色彩空间的介绍,但是直到今天才自己动手写代码做这件事情。虽然网络上已经有很多现成的例子,但是一则仅仅适用于浮点型的数据,另一方面,在实现上也有一些尚可优化之处。
|
|
2214 |
|
|
2215 |
色彩模型除了最常见的RGB以外,还有HSB、YCbCr、XYZ、Lab等。HSB一般仅仅作为图像处理过程中的临时模式,YCbCr常常用于图像的压缩处理,而XYZ则严格按照人眼对光信号的敏感度进行分布。
|
|
2216 |
|
|
2217 |
这里将要稍作讨论的便是Lab模型。网络上诸多的介绍都说Lab是基于XYZ的,故人们一般也只能找到XYZ和Lab之间的转换,而RGB到Lab的转换只能使用XYZ作为中间模式间接进行。可惜的是,这种现状源于误解。而在图像处理软件中(比如Photoshop),往往采用一个更为简单的算法。
|
|
2218 |
|
|
2219 |
我们可以先观察RGB到XYZ的转换:
|
|
2220 |
[X,Y,Z] = [M] * [R,G,B]
|
|
2221 |
|
|
2222 |
其中M为一3x3矩阵:
|
|
2223 |
[M] = [0.4125, 0.3576, 0.1805;
|
|
2224 |
0.2126, 0.7152, 0.0722;
|
|
2225 |
0.0193, 0.1192, 0.9505],
|
|
2226 |
|
|
2227 |
RGB是经过Gamma校正的色彩分量:R=g(r),G=g(g),B=g(b)。
|
|
2228 |
其中rgb为原始的色彩分量。
|
|
2229 |
|
|
2230 |
g是Gamma校正函数:
|
|
2231 |
当 x < 0.018 时,g(x) = 4.5318 * x
|
|
2232 |
当 x >= 0.018 时,g(x) = 1.099 * d^0.45 - 0.099
|
|
2233 |
|
|
2234 |
rgb以及RGB的取值范围则均为[0,1)。计算完成后,XYZ的取值范围则有所变化,分别是:[0, 0.9506),[0, 1),[0, 1.0890)。
|
|
2235 |
|
|
2236 |
|
|
2237 |
以及XYZ到Lab的转换:
|
|
2238 |
L = 116 * f(Y1) - 16
|
|
2239 |
a = 500 * (f(X1) - f(Y1))
|
|
2240 |
b = 200 * (f(Y1) - f(Z1))
|
|
2241 |
|
|
2242 |
其中f是一个类似Gamma函数的校正函数:
|
|
2243 |
当 x > 0.008856 时,f(x) = x^(1/3)
|
|
2244 |
当 x <= 0.008856 时,f(x) = ( 7.787 * x ) + ( 16 / 116 )
|
|
2245 |
X1、Y1、Z1分别是线性归一化之后的XYZ值,也就是说,它们的取值范围都是[0, 1)。此外,函数f的值域也和自变量一样都是[0, 1)。
|
|
2246 |
|
|
2247 |
计算完成后,L的取值范围[0, 100),而a和b则约为[-169, +169)和[-160, +160)。
|
|
2248 |
|
|
2249 |
|
|
2250 |
在观察这些貌似复杂的变换之前,我们必须确定的一个假设是:在图像处理软件中,非RGB色彩数据的绝对值并不重要,重要的是他们能够尽可能准确的还原成RGB图像以显示在屏幕等相关设备上。这个假设是我们的简化得以成立的理由。
|
|
2251 |
|
|
2252 |
上面的从XYZ到Lab的转换乍一看起来很奇怪,但若是仔细观察,不难发现L与Y1只是一个简单的同区间映射关系,这个映射其实可有可无(如果进行了映射反而必定导致色阶丢失)。
|
|
2253 |
|
|
2254 |
这样,我们取得的第一个简化是:L = Y1。
|
|
2255 |
|
|
2256 |
接下来接着看a和b的映射过程。大家不难发现,a和b其实是一个色差信号(跟Cb和Cr的性质差不多)。至于它们的转换系数500和200,大家可以完全忘记,因为他们的值域并不符合8位整数值的表达需要。我们将会稍后计算出合适的因数,使得a和b都处在[0, 255]的范围内。
|
|
2257 |
|
|
2258 |
因为XYZ必须归一化转为X1Y1Z1,那么我们其实可以在转换矩阵M中作出这个修改,令每行乘以一个系数以使得每行各数之和为1:
|
|
2259 |
[M1] = [0.4339, 0.3762 0.1899;
|
|
2260 |
0.2126, 0.7152, 0.0722;
|
|
2261 |
0.0177, 0.1095, 0.8728]
|
|
2262 |
|
|
2263 |
于是乎,我们得出一个半成品:
|
|
2264 |
L = Y1 = 0.2126 * R + 0.7152 * G + 0.0722 * B
|
|
2265 |
a = Fa * (X1 - Y1) + Da
|
|
2266 |
b = Fb * (Y1 - Z1) + Db
|
|
2267 |
其中的Fx是调整值域用的系数,Dx是一个正数,用来消除a和b的负值。Fx和Dx的选取必须令a和b满足值域在[0, 255]上的分布。
|
|
2268 |
|
|
2269 |
接下来我们来确定Fx和Dx的值。通过M1我们很容易计算出X1-Y1的值域(极端情况)为[-86.784, +86.784),而Y1-Z1的值域则为[-204.9536, +204.9536)。于是乎,Fa的值为1.4749,Fb的值为0.6245;Da和Db则都是128。
|
|
2270 |
|
|
2271 |
这时,代入M1有:
|
|
2272 |
L = Y1 = 0.2126 * R + 0.7152 * G + 0.0722 * B
|
|
2273 |
a = 1.4749 * (0.2213 * R - 0.3390 * G + 0.1177 * B) + 128
|
|
2274 |
b = 0.6245 * (0.1949 * R + 0.6057 * G - 0.8006 * B) + 128
|
|
2275 |
其中RGB和Lab的取值范围都是[0,255]。
|
|
2276 |
|
|
2277 |
最后的一点工作是算法的优化。我们可以将这个方程组转换成常整数乘法与移位的方式(相当于使用定点数)。为了方便阅读,我仍然将移位写为除法。
|
|
2278 |
|
|
2279 |
所以我们的最终结果为:
|
|
2280 |
L = Y1 = (13933 * R + 46871 * G + 4732 * B) div 2^16
|
|
2281 |
a = 377 * (14503 * R - 22218 * G + 7714 * B) div 2^24 + 128
|
|
2282 |
b = 160 * (12773 * R + 39695 * G - 52468 * B) div 2^24 + 128
|
|
2283 |
|
|
2284 |
|
|
2285 |
至于逆变换则可以用类似的方法推导出来:
|
|
2286 |
设L1=L,a1=(a-128)*174,b1=(b-128)*410,有:
|
|
2287 |
R = L1 + (a1 * 100922 + b1 * 17790) div 2^23
|
|
2288 |
G = L1 - (a1 * 30176 + b1 * 1481) div 2^23
|
|
2289 |
B = L1 + (a1 * 1740 - b1 * 37719) div 2^23
|
|
2290 |
其中RGB和Lab的取值范围都是[0,255],再经过逆Gamma函数取得原始的rgb
|
|
2291 |
|
|
2292 |
|
|
2293 |
以上的算法在Delphi中编译通过。经测试,运算得出的直方图与图片观感和我手头的Photoshop CS的结果非常相似,但也有一些幅度上的差别,且容以后慢慢细察。
|
|
2294 |
|
|
2295 |
当初为了寻觅一个简单的RGB直接转Lab算法而找遍网络皆不得,万不得已只好自力更生。其间虽费时一日,幸好也算略有所得。暂记于此,以利后人。其间或许难免错漏之处,还望达人不吝指点。
|
|
2296 |
|
|
2297 |
|
|
2298 |
|
|
2299 |
*/
|
|
2300 |
Lab RGBfToLab(COLORf &c1f)
|
|
2301 |
{
|
|
2302 |
float X,Y,Z,fX,fY,fZ;
|
|
2303 |
Lab lab1;
|
|
2304 |
float R,G,B;
|
|
2305 |
R=c1f.R;
|
|
2306 |
G=c1f.G;
|
|
2307 |
B=c1f.B;
|
|
2308 |
// if (!(R>=0)||!(R<=256))
|
|
2309 |
// {
|
|
2310 |
// lab1.L=0;lab1.a=0;lab1.b=0;
|
|
2311 |
// return lab1;
|
|
2312 |
// }
|
|
2313 |
|
|
2314 |
X = (0.0017017755110158063242130877282104f*R + 0.0014753702536507966372219765884924f*G + 0.00074442286278437743072179842839524f*B);
|
|
2315 |
Y = (0.00083400392156862745098039215686275f*R + 0.0028045490196078431372549019607843f*G + 0.00028301568627450980392156862745098f*B);
|
|
2316 |
Z = (0.000069638878794601218367014756605923f*R + 0.00042931968967440276305056325044635f*G + 0.0034226100589819764107392847380458f*B);
|
|
2317 |
|
|
2318 |
if (Y > 0.008856451679f) // 进行修正, (6/29)^3 ,约 1/113;
|
|
2319 |
{
|
|
2320 |
fY = pow(Y,(1.0f/3));
|
|
2321 |
lab1.L= 116*fY - 16;
|
|
2322 |
}
|
|
2323 |
else
|
|
2324 |
{
|
|
2325 |
fY = 7.787f*Y + 16.0f/116;
|
|
2326 |
lab1.L= 903.3f*Y;
|
|
2327 |
}
|
|
2328 |
if (X > 0.008856451679f) // 进行修正, (6/29)^3 ,约 1/113;
|
|
2329 |
fX = pow(X,(1.0f/3));
|
|
2330 |
else fX = 7.787f*X + 16.0f/116;
|
|
2331 |
|
|
2332 |
if (Z > 0.008856451679f) // 进行修正, (6/29)^3 ,约 1/113;
|
|
2333 |
fZ = pow(Z,(1.0f/3));
|
|
2334 |
else fZ = 7.787f*Z + 16.0f/116;
|
|
2335 |
|
|
2336 |
lab1.a = 500.0f*(fX - fY) +128;
|
|
2337 |
lab1.b = 200.0f*(fY - fZ) +128;
|
|
2338 |
return lab1;
|
|
2339 |
|
|
2340 |
}
|
|
2341 |
COLORf LabToRGBf(Lab lab1)
|
|
2342 |
{
|
|
2343 |
float X,Y,Z,fX,fY,fZ;
|
|
2344 |
COLORf c1f;
|
|
2345 |
float L,a,b;
|
|
2346 |
a = lab1.a-128;
|
|
2347 |
b = lab1.b-128;
|
|
2348 |
L=lab1.L;
|
|
2349 |
fY = pow(((L + 16) / 116.0f),3.0f);
|
|
2350 |
if (fY <= 0.008856f) {fY = L / 903.3f;}
|
|
2351 |
Y = fY;
|
|
2352 |
if (Y > 0.008856f) {fY = pow(Y,(1.0f/3));}
|
|
2353 |
if (Y <= 0.008856f) {fY = 7.787f * Y + 16.0f/116;}
|
|
2354 |
|
|
2355 |
fX = a / 500 + fY;
|
|
2356 |
if (fX > 0.206893f) {X = pow(fX,(3.0f));}
|
|
2357 |
if (fX <= 0.206893f) {X = (fX - 16.0f/116) / 7.787f;}
|
|
2358 |
|
|
2359 |
fZ = fY - b /200;
|
|
2360 |
if (fZ > 0.206893f) {Z = pow(fZ,(3.0f));}
|
|
2361 |
if (fZ <= 0.206893f) {Z = (fZ - 16.0f/116) / 7.787f;}
|
|
2362 |
|
|
2363 |
X = X * 0.950456f * 255;
|
|
2364 |
Y = Y *255;
|
|
2365 |
Z = Z * 1.088754f * 255;
|
|
2366 |
|
|
2367 |
c1f.R = 3.240479f*X - 1.537150f*Y - 0.498535f*Z;
|
|
2368 |
c1f.G =-0.969256f*X + 1.875992f*Y + 0.041556f*Z;
|
|
2369 |
c1f.B = 0.055648f*X - 0.204043f*Y + 1.057311f*Z;
|
|
2370 |
return c1f;
|
|
2371 |
}
|
|
2372 |
HSI RGBfToHSI(COLORf &c1)
|
|
2373 |
{
|
|
2374 |
float nMax,nMin,ndelMax;
|
|
2375 |
float ndelR,ndelG,ndelB;
|
|
2376 |
float nH,nS,nV;
|
|
2377 |
float nR,nB,nG;
|
|
2378 |
HSI hsb2;
|
|
2379 |
nR=c1.R/255.0f;
|
|
2380 |
nG=c1.G/255.0f;
|
|
2381 |
nB=c1.B/255.0f;
|
|
2382 |
if (!(nR>=0)||!(nR<=256))
|
|
2383 |
{
|
|
2384 |
hsb2.H=0;hsb2.S=0;hsb2.I=0;
|
|
2385 |
return hsb2;
|
|
2386 |
}
|
|
2387 |
nMax=max(nR,max(nG,nB));
|
|
2388 |
nMin=min(nR,min(nG,nB));
|
|
2389 |
ndelMax=nMax-nMin;
|
|
2390 |
nV=nMax;
|
|
2391 |
|
|
2392 |
if (ndelMax==0) {nS=0;nH=0;} //最大值与最小值相等,纯色。
|
|
2393 |
else
|
|
2394 |
{
|
|
2395 |
nS=ndelMax/nMax;
|
|
2396 |
ndelR = (((nMax - nR) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
|
2397 |
ndelG = (((nMax - nG) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
|
2398 |
ndelB = (((nMax - nB) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
|
|
2399 |
if (nR==nMax)
|
|
2400 |
{
|
|
2401 |
nH = ndelB - ndelG;
|
|
2402 |
}
|
|
2403 |
else if (nG==nMax)
|
|
2404 |
{
|
|
2405 |
nH = (1.0f / 3) + ndelR - ndelB;
|
|
2406 |
|
|
2407 |
}
|
|
2408 |
else if (nB==nMax)
|
|
2409 |
{
|
|
2410 |
nH = (2.0f / 3) + ndelG - ndelR;
|
|
2411 |
}
|
|
2412 |
if (nH<0) {nH+=1;}
|
|
2413 |
if (nH>1) {nH-=1;}
|
|
2414 |
|
|
2415 |
}
|
|
2416 |
hsb2.H =(nH*240);
|
|
2417 |
hsb2.S =(nS*240);
|
|
2418 |
hsb2.I =(nV*240);
|
|
2419 |
|
|
2420 |
return hsb2 ;
|
|
2421 |
}
|
|
2422 |
|
|
2423 |
DWORD HSIToRGB(HSI hsb1)
|
|
2424 |
{
|
|
2425 |
COLOR color2;
|
|
2426 |
float nH,nS,nV;
|
|
2427 |
float nR,nG,nB;
|
|
2428 |
float f,p,q,t;
|
|
2429 |
int k;
|
|
2430 |
nH=hsb1.H/240.0f;
|
|
2431 |
nS=hsb1.S/240.0f;
|
|
2432 |
nV=hsb1.I/240.0f;
|
|
2433 |
k = (int)( (int(hsb1.H) / 40) % 6);
|
|
2434 |
f = (hsb1.H / 40.0f) - k;
|
|
2435 |
p=nV*(1-nS);
|
|
2436 |
q=nV*(1-f*nS);
|
|
2437 |
t=nV*(1-(1-f)*nS);
|
|
2438 |
if (k==0)
|
|
2439 |
{
|
|
2440 |
nR=nV;nG=t;nB=p;
|
|
2441 |
} else if (k==1)
|
|
2442 |
{ nR=q;nG=nV;nB=p;
|
|
2443 |
} else if (k==2)
|
|
2444 |
{ nR=p;nG=nV;nB=t;
|
|
2445 |
} else if (k==3)
|
|
2446 |
{ nR=p;nG=q;nB=nV;
|
|
2447 |
} else if (k==4)
|
|
2448 |
{ nR=t;nG=p;nB=nV;}
|
|
2449 |
else if (k==5)
|
|
2450 |
{ nR=nV;nG=p;nB=q;}
|
|
2451 |
color2.R=int(nR*255);color2.G=int(nG*255);color2.B=int(nB*255);
|
|
2452 |
//R=nV*100;G=nV*100;B=nV*100;
|
|
2453 |
|
|
2454 |
return color2.argb ;
|
|
2455 |
}
|
|
2456 |
|
|
2457 |
COLORf HSIToRGBf(HSI hsb1)
|
|
2458 |
{
|
|
2459 |
COLORf color2;
|
|
2460 |
float nH,nS,nV;
|
|
2461 |
float nR,nG,nB;
|
|
2462 |
float f,p,q,t;
|
|
2463 |
int k;
|
|
2464 |
nH=hsb1.H/240.0f;
|
|
2465 |
nS=hsb1.S/240.0f;
|
|
2466 |
nV=hsb1.I/240.0f;
|
|
2467 |
k = (int)( (int(hsb1.H) / 40) % 6);
|
|
2468 |
f = (hsb1.H / 40.0f) - k;
|
|
2469 |
p=nV*(1-nS);
|
|
2470 |
q=nV*(1-f*nS);
|
|
2471 |
t=nV*(1-(1-f)*nS);
|
|
2472 |
if (k==0)
|
|
2473 |
{
|
|
2474 |
nR=nV;nG=t;nB=p;
|
|
2475 |
} else if (k==1)
|
|
2476 |
{ nR=q;nG=nV;nB=p;
|
|
2477 |
} else if (k==2)
|
|
2478 |
{ nR=p;nG=nV;nB=t;
|
|
2479 |
} else if (k==3)
|
|
2480 |
{ nR=p;nG=q;nB=nV;
|
|
2481 |
} else if (k==4)
|
|
2482 |
{ nR=t;nG=p;nB=nV;}
|
|
2483 |
else if (k==5)
|
|
2484 |
{ nR=nV;nG=p;nB=q;}
|
|
2485 |
color2.R=nR*255;color2.G=nG*255;color2.B=nB*255;
|
|
2486 |
//R=nV*100;G=nV*100;B=nV*100;
|
|
2487 |
|
|
2488 |
return color2 ;
|
|
2489 |
}
|
|
2490 |
|
|
2491 |
#define EVEN(x) ((srcbuf[(x)*3/2]<<4)+(srcbuf[(x)*3/2+1]&0xf))
|
|
2492 |
#define ODD(x) (((*(unsigned short *)(&srcbuf[(x)*3/2+1]))>>4)&0x0fff)
|
|
2493 |
int Raw12toRaw16(void * dest,void * src,int width,int height)
|
|
2494 |
{
|
|
2495 |
int i,l;//,k,l;
|
|
2496 |
unsigned short int a,b;
|
|
2497 |
unsigned short int * destbuf=(unsigned short *)dest;
|
|
2498 |
unsigned char * srcbuf=(unsigned char *)src;
|
|
2499 |
l=width*height;
|
|
2500 |
// memcpy(destbuf,srcbuf,l);
|
|
2501 |
// memcpy(destbuf+width*height/2,srcbuf,l);
|
|
2502 |
// return 0;
|
|
2503 |
for (i=0;i<l;i+=2)
|
|
2504 |
{
|
|
2505 |
// a=(srcbuf[i*3/2]<<8)+((srcbuf[i*3/2+1]&0x0f)<<4);
|
|
2506 |
// b=(srcbuf[i*3/2+2]<<8)+(srcbuf[i*3/2+1]&0xf0);
|
|
2507 |
a=EVEN(i)*16;
|
|
2508 |
b=ODD(i)*16;
|
|
2509 |
destbuf[i]=a;
|
|
2510 |
destbuf[i+1]=b;
|
|
2511 |
}
|
|
2512 |
return 0;
|
|
2513 |
}
|
|
2514 |
|
|
2515 |
int Raw12ToRaw8(void * dest, void * src, int width, int height)
|
|
2516 |
{
|
|
2517 |
int i,l; //j,k,
|
|
2518 |
// unsigned short int a,b;
|
|
2519 |
unsigned char * destbuf=(unsigned char *)dest;
|
|
2520 |
unsigned char * srcbuf=(unsigned char *)src;
|
|
2521 |
l=width*height;
|
|
2522 |
// memcpy(destbuf,srcbuf,l);
|
|
2523 |
// memcpy(destbuf+width*height/2,srcbuf,l);
|
|
2524 |
// return 0;
|
|
2525 |
for (i=0;i<l;i+=2)
|
|
2526 |
{
|
|
2527 |
// a=(srcbuf[i*3/2]<<8)+((srcbuf[i*3/2+1]&0x0f)<<4);
|
|
2528 |
// b=(srcbuf[i*3/2+2]<<8)+(srcbuf[i*3/2+1]&0xf0);
|
|
2529 |
//a=EVEN(i)*16;
|
|
2530 |
//b=ODD(i)*16;
|
|
2531 |
destbuf[i]=srcbuf[i*3/2];
|
|
2532 |
destbuf[i+1]=srcbuf[i*3/2+2];
|
|
2533 |
}
|
|
2534 |
return 0;
|
|
2535 |
}
|
|
2536 |
|
|
2537 |
int BayerGB12PackedToRGB32(void * dest,void * src,int width,int height,float gamma)
|
|
2538 |
{
|
|
2539 |
int i,j,k,l,m,n,p;
|
|
2540 |
// unsigned short int a,b;
|
|
2541 |
COLOR * destbuf=(COLOR *)dest;
|
|
2542 |
unsigned char * srcbuf=(unsigned char *)src;
|
|
2543 |
// return 0;
|
|
2544 |
unsigned char LUTgamma[4096];
|
|
2545 |
for (i=0;i<4096;i++)
|
|
2546 |
{
|
|
2547 |
j=int(pow(i/4096.0f,gamma)*256+0.5);
|
|
2548 |
if (j>255) {j=255;}
|
|
2549 |
LUTgamma[i]=j;
|
|
2550 |
|
|
2551 |
}
|
|
2552 |
unsigned short int buf1[4][3200];
|
|
2553 |
unsigned short int G00,B01,G02,B03;
|
|
2554 |
unsigned short int R10,G11,R12,G13;
|
|
2555 |
unsigned short int G20,B21,G22,B23;
|
|
2556 |
unsigned short int R30,G31,R32,G33;
|
|
2557 |
|
|
2558 |
for (i=0;i<3;i++)
|
|
2559 |
{
|
|
2560 |
l=i*width;
|
|
2561 |
for (j=0;j<width;j+=2)
|
|
2562 |
{
|
|
2563 |
buf1[i][j]=EVEN(l+j);buf1[i][j+1]=ODD(l+j);
|
|
2564 |
}
|
|
2565 |
}
|
|
2566 |
|
|
2567 |
for (i=0;i<height-2;i+=2)
|
|
2568 |
{
|
|
2569 |
l=i*width;
|
|
2570 |
m=l+width;
|
|
2571 |
n=m+width;
|
|
2572 |
p=n+width;
|
|
2573 |
for (j=0;j<width;j+=4)
|
|
2574 |
{
|
|
2575 |
k=*(unsigned *)(srcbuf+(n+j)*3/2);
|
|
2576 |
*((unsigned *)&buf1[(i+2)&0x3][j])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
|
|
2577 |
k=*(unsigned *)(srcbuf+(n+j+2)*3/2);
|
|
2578 |
*((unsigned *)&buf1[(i+2)&0x3][j+2])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
|
|
2579 |
// buf1[(i+2)&0x3][j]=EVEN(n+j);buf1[(i+2)&0x3][j+1]=ODD(n+j);
|
|
2580 |
// buf1[(i+2)&0x3][j+2]=EVEN(n+j+2);buf1[(i+2)&0x3][j+3]=ODD(n+j+2);
|
|
2581 |
|
|
2582 |
}
|
|
2583 |
for (j=0;j<width;j+=4)
|
|
2584 |
{
|
|
2585 |
k=*(unsigned *)(srcbuf+(p+j)*3/2);
|
|
2586 |
*((unsigned *)&buf1[(i+3)&0x3][j])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
|
|
2587 |
k=*(unsigned *)(srcbuf+(p+j+2)*3/2);
|
|
2588 |
*((unsigned *)&buf1[(i+3)&0x3][j+2])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
|
|
2589 |
// buf1[(i+3)&0x3][j]=EVEN(p+j);buf1[(i+3)&0x3][j+1]=ODD(p+j);
|
|
2590 |
// buf1[(i+3)&0x3][j+2]=EVEN(p+j+2);buf1[(i+3)&0x3][j+3]=ODD(p+j+2);
|
|
2591 |
|
|
2592 |
}
|
|
2593 |
|
|
2594 |
for (j=0;j<width-2;j+=2)
|
|
2595 |
{
|
|
2596 |
// G00=EVEN(l+j);B01=ODD(l+j);G02=EVEN(l+j+2);B03=ODD(l+j+2);
|
|
2597 |
// R10=EVEN(m+j);G11=ODD(m+j);R12=EVEN(m+j+2);G13=ODD(m+j+2);
|
|
2598 |
// G20=EVEN(n+j);B21=ODD(n+j);G22=EVEN(n+j+2);B23=ODD(n+j+2);
|
|
2599 |
// R30=EVEN(p+j);G31=ODD(p+j);R32=EVEN(p+j+2);G33=ODD(p+j+2);
|
|
2600 |
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];
|
|
2601 |
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];
|
|
2602 |
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];
|
|
2603 |
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];
|
|
2604 |
/*
|
|
2605 |
destbuf[l+j].B=LUTgamma[B01];destbuf[l+j].G=LUTgamma[(G00+G11)/2];destbuf[l+j].R=LUTgamma[R10];
|
|
2606 |
destbuf[l+j+1].B=LUTgamma[B01];destbuf[l+j+1].G=LUTgamma[(G11+G02)/2];destbuf[l+j+1].R=LUTgamma[R12];
|
|
2607 |
|
|
2608 |
destbuf[m+j].B=LUTgamma[B21];destbuf[m+j].G=LUTgamma[(G20+G11)/2];destbuf[m+j].R=LUTgamma[R10];
|
|
2609 |
destbuf[m+j+1].B=LUTgamma[B21];destbuf[m+j+1].G=LUTgamma[(G11+G22)/2];destbuf[m+j+1].R=LUTgamma[R12];
|
|
2610 |
*/
|
|
2611 |
|
|
2612 |
destbuf[m+j+1].B=LUTgamma[(B01+B21)/2];
|
|
2613 |
destbuf[m+j+1].G=LUTgamma[G11];
|
|
2614 |
destbuf[m+j+1].R=LUTgamma[(R10+R12)/2];
|
|
2615 |
|
|
2616 |
destbuf[m+j+2].B=LUTgamma[(B01+B21+B03+B23)/4];
|
|
2617 |
if (abs(G02-G22)<abs(G11-G13)) {destbuf[m+j+2].G=LUTgamma[(G02+G22)/2];}
|
|
2618 |
else if (abs(G02-G22)>abs(G11-G13)) {destbuf[m+j+2].G=LUTgamma[(G11+G13)/2];}
|
|
2619 |
else {destbuf[m+j+2].G=LUTgamma[(G02+G22+G11+G13)/4];}
|
|
2620 |
destbuf[m+j+2].R=LUTgamma[R12];
|
|
2621 |
|
|
2622 |
destbuf[n+j+1].B=LUTgamma[B21];
|
|
2623 |
if (abs(G11-G31)<abs(G20-G22)) {destbuf[n+j+1].G=LUTgamma[(G11+G31)/2];}
|
|
2624 |
else if (abs(G11-G31)>abs(G20-G22)) {destbuf[n+j+1].G=LUTgamma[(G20+G22)/2];}
|
|
2625 |
else {destbuf[n+j+1].G=LUTgamma[(G11+G31+G20+G22)/4];}
|
|
2626 |
destbuf[n+j+1].R=LUTgamma[(R10+R30+R12+R32)/4];
|
|
2627 |
|
|
2628 |
destbuf[n+j+2].B=LUTgamma[(B21+B23)/2];
|
|
2629 |
destbuf[n+j+2].G=LUTgamma[G22];
|
|
2630 |
destbuf[n+j+2].R=LUTgamma[(R12+R32)/2];
|
|
2631 |
|
|
2632 |
|
|
2633 |
}
|
|
2634 |
}
|
|
2635 |
return 0;
|
|
2636 |
}
|
|
2637 |
|
|
2638 |
/*
|
|
2639 |
|
|
2640 |
|
|
2641 |
R03=srcbuf[k+2];
|
|
2642 |
B12=srcbuf[l+1];G13=srcbuf[l+2];
|
|
2643 |
G22=srcbuf[m+1];R23=srcbuf[m+2];
|
|
2644 |
B32=srcbuf[n+1];
|
|
2645 |
|
|
2646 |
|
|
2647 |
for (j=2;j<width-6;j+=2)
|
|
2648 |
{
|
|
2649 |
// 奇数行
|
|
2650 |
R01=R03; G02=srcbuf[k+j+1]; R03=srcbuf[k+j+2];
|
|
2651 |
B10=B12; G11=G13; B12=srcbuf[l+j+1]; G13=srcbuf[l+j+2];
|
|
2652 |
G20=G22; R21=R23; G22=srcbuf[m+j+1]; R23=srcbuf[m+j+2];
|
|
2653 |
B30=B32; G31=srcbuf[n+j]; B32=srcbuf[n+j+1];
|
|
2654 |
|
|
2655 |
*/
|
|
2656 |
|
|
2657 |
int BayerGB16toRGB64(void * dest,void * src,int width,int height)
|
|
2658 |
{
|
|
2659 |
int i,j,k,l,m,n,p,q,s;
|
|
2660 |
//unsigned short R,G,B,R1,R2,R3,R4,G1,G2,G3,G4,B1,B2,B3,B4;
|
|
2661 |
unsigned short G00, B01, G02, B03, G04, B05;
|
|
2662 |
unsigned short R10, G11, R12, G13, R14, G15;
|
|
2663 |
unsigned short G20, B21, G22, B23, G24, B25;
|
|
2664 |
unsigned short R30, G31, R32, G33, R34, G35;
|
|
2665 |
unsigned short G40, B41, G42, B43, G44, B45;
|
|
2666 |
unsigned short R50, G51, R52, G53, R54, G55;
|
|
2667 |
|
|
2668 |
unsigned long long * destbuf=(unsigned long long *) dest;
|
|
2669 |
unsigned short * srcbuf=(unsigned short *)src;
|
|
2670 |
s=width;
|
|
2671 |
G00=0;
|
|
2672 |
RGB16 pixel;
|
|
2673 |
|
|
2674 |
for (i=2;i<height-4;i+=2)
|
|
2675 |
{
|
|
2676 |
k=i*width-width-width; //上一行
|
|
2677 |
l=i*width-width; //当前行
|
|
2678 |
m=i*width; //下一行
|
|
2679 |
n=m+width; //下两行
|
|
2680 |
p=m+width+width;
|
|
2681 |
q=m+width+width+width;
|
|
2682 |
B01=srcbuf[k+1];G02=srcbuf[k+2];B03=srcbuf[k+3];G04=srcbuf[k+4];B05=srcbuf[k+5];
|
|
2683 |
R10=srcbuf[l+0];G11=srcbuf[l+1];R12=srcbuf[l+2];G13=srcbuf[l+3];R14=srcbuf[l+4];G15=srcbuf[l+5];
|
|
2684 |
G20=srcbuf[m+0];B21=srcbuf[m+1];G22=srcbuf[m+2];B23=srcbuf[m+3];G24=srcbuf[m+4];B25=srcbuf[m+5];
|
|
2685 |
R30=srcbuf[n+0];G31=srcbuf[n+1];R32=srcbuf[n+2];G33=srcbuf[n+3];R34=srcbuf[n+4];G35=srcbuf[n+5];
|
|
2686 |
G40=srcbuf[p+0];B41=srcbuf[p+1];G42=srcbuf[p+2];B43=srcbuf[p+3];G44=srcbuf[p+4];B45=srcbuf[p+5];
|
|
2687 |
R50=srcbuf[q+0];G51=srcbuf[q+1];R52=srcbuf[q+2];G53=srcbuf[q+3];R54=srcbuf[q+4];G55=srcbuf[q+5];
|
|
2688 |
|
|
2689 |
for (j=2;j<width-6;j+=2)
|
|
2690 |
{
|
|
2691 |
// 奇数行
|
|
2692 |
|
|
2693 |
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];
|
|
2694 |
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];
|
|
2695 |
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];
|
|
2696 |
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];
|
|
2697 |
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];
|
|
2698 |
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];
|
|
2699 |
|
|
2700 |
pixel.B=(B21+B23)/2;
|
|
2701 |
pixel.G=G22;
|
|
2702 |
pixel.R=(R12+R32)/2;
|
|
2703 |
((RGB16 *)(&destbuf[m+j]))->ARGB=pixel.ARGB ;
|
|
2704 |
|
|
2705 |
pixel.B=B23;
|
|
2706 |
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
|
2707 |
//else{pixel.G=(G22+G24)/2;}
|
|
2708 |
if (abs(signed(B03+B43-B23*2))<abs(signed(B21+B25-B23*2))) {pixel.G=(G13+G33)/2;}
|
|
2709 |
else {pixel.G=(G22+G24)/2;}
|
|
2710 |
|
|
2711 |
pixel.R=((unsigned int )R12+R32+R14+R34)/4;
|
|
2712 |
destbuf[m+j+1]=pixel.ARGB ;
|
|
2713 |
|
|
2714 |
//偶数行
|
|
2715 |
pixel.B=((unsigned int )B21+B41+B23+B43)/4;
|
|
2716 |
if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
|
2717 |
else{pixel.G=(G31+G33)/2;}
|
|
2718 |
|
|
2719 |
pixel.R=R32;
|
|
2720 |
destbuf[n+j]=pixel.ARGB ;
|
|
2721 |
|
|
2722 |
pixel.B=(B23+B43)/2;
|
|
2723 |
pixel.G=G33;
|
|
2724 |
pixel.R=(R32+R34)/2;
|
|
2725 |
destbuf[n+j+1]=pixel.ARGB ;
|
|
2726 |
}
|
|
2727 |
}
|
|
2728 |
return 0;
|
|
2729 |
}
|
|
2730 |
int RGB64toRGB32(void * destbuf,void * srcbuf,int width,int height)
|
|
2731 |
{
|
|
2732 |
int i,j,l,s;
|
|
2733 |
s=width;
|
|
2734 |
l=width*height;
|
|
2735 |
RGB16 * pixel=(RGB16 *)srcbuf;
|
|
2736 |
COLOR * c1=(COLOR *) destbuf;
|
|
2737 |
for (i=0;i<height;i++)
|
|
2738 |
{
|
|
2739 |
l=s*i;
|
|
2740 |
for (j=0;j<width;j++)
|
|
2741 |
{
|
|
2742 |
c1[l+j].R=pixel[l+j].R>>8;
|
|
2743 |
c1[l+j].G=pixel[l+j].G>>8;
|
|
2744 |
c1[l+j].B=pixel[l+j].B>>8;
|
|
2745 |
c1[l+j].A=pixel[l+j].A>>8;
|
|
2746 |
}
|
|
2747 |
}
|
|
2748 |
return 0;
|
|
2749 |
}
|
|
2750 |
|
|
2751 |
int RGB32toRGB64(void * destbuf,void * srcbuf,int width,int height)
|
|
2752 |
{
|
|
2753 |
int i,l;
|
|
2754 |
l=width*height;
|
|
2755 |
RGB16 * pixel=(RGB16 *)destbuf;
|
|
2756 |
COLOR * c1=(COLOR *)srcbuf;
|
|
2757 |
for (i=0;i<l;i++)
|
|
2758 |
{
|
|
2759 |
pixel[i].R=c1[i].R<<8;
|
|
2760 |
pixel[i].G=c1[i].G<<8;
|
|
2761 |
pixel[i].B=c1[i].B<<8;
|
|
2762 |
pixel[i].A=c1[i].A<<8;
|
|
2763 |
}
|
|
2764 |
return 0;
|
|
2765 |
}
|
|
2766 |
/*
|
|
2767 |
float CalHSIDistance(HSI hsb1, HSI hsb2)
|
|
2768 |
{
|
|
2769 |
float nH1,nH2,nS1,nS2,nV1,nV2;
|
|
2770 |
float delH,delS,delV;
|
|
2771 |
float kH,kS,kV;
|
|
2772 |
CString s1;
|
|
2773 |
float PercentH,PercentS,PercentV;
|
|
2774 |
PercentH=1.0f;PercentS=0.10f;PercentV=0.05f;
|
|
2775 |
kH=PercentH;//1.0f
|
|
2776 |
kS=PercentS;//0.4f;
|
|
2777 |
kV=PercentV;//0.1f;
|
|
2778 |
nH1=hsb1.H/240.0f;nH2=hsb2.H/240.0f;
|
|
2779 |
nS1=hsb1.S/240.0f;nS2=hsb2.S/240.0f;
|
|
2780 |
nV1=hsb1.I/240.0f;nV2=hsb2.I/240.0f;
|
|
2781 |
delH=nH1-nH2;
|
|
2782 |
delS=nS1-nS2;
|
|
2783 |
delV=nV1-nV2;
|
|
2784 |
float distance;
|
|
2785 |
if (delH<0) {delH+=1;}
|
|
2786 |
if (delH>0.5) {delH=1-delH;}
|
|
2787 |
|
|
2788 |
distance=sqrtf(kH*kH*delH*delH+kS*kS*delS*delS+kV*kV*delV*delV)*240.0f;
|
|
2789 |
// 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);
|
|
2790 |
// SysLog(s1);
|
|
2791 |
return distance;
|
|
2792 |
return 0;
|
|
2793 |
}
|
|
2794 |
*/
|
|
2795 |
/*
|
|
2796 |
float Calk(HSI hsb0,HSI hsb1,HSI hsb2)
|
|
2797 |
{
|
|
2798 |
float k; //计算空间点对直线的垂足位置,即垂足在直线上的两点之间的比例。
|
|
2799 |
//hsb0为空间点,hsb1和hsb2确定空间直线。
|
|
2800 |
float x0,x1,x2,y0,y1,y2,z0,z1,z2;
|
|
2801 |
float PercentH,PercentS,PercentV;
|
|
2802 |
PercentH=1.0f;PercentS=0.10f;PercentV=0.05f;
|
|
2803 |
x0=hsb0.H*PercentH;
|
|
2804 |
x1=hsb1.H*PercentH;
|
|
2805 |
x2=hsb2.H*PercentH;
|
|
2806 |
y0=hsb0.S*PercentS;
|
|
2807 |
y1=hsb1.S*PercentS;
|
|
2808 |
y2=hsb2.S*PercentS;
|
|
2809 |
z0=hsb0.I*PercentV;
|
|
2810 |
z1=hsb1.I*PercentV;
|
|
2811 |
z2=hsb2.I*PercentV;
|
|
2812 |
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));
|
|
2813 |
return k;
|
|
2814 |
}
|
|
2815 |
*/
|
|
2816 |
/*
|
|
2817 |
float CalPos(HSI hsb1)
|
|
2818 |
{
|
|
2819 |
float n;
|
|
2820 |
int i;
|
|
2821 |
int lastCheckedClass=0;
|
|
2822 |
float kPosition[maxClasses];
|
|
2823 |
HSI chsb1,chsb2;
|
|
2824 |
HSI hsbs[100];
|
|
2825 |
float Nf[100];
|
|
2826 |
float distancehsb[100];
|
|
2827 |
int TotalHsbs;
|
|
2828 |
float k;
|
|
2829 |
//先将所有颜色点统计出来;还有各颜色点对应的分值;
|
|
2830 |
TotalHsbs=0;
|
|
2831 |
for (i=0;i<TotalClasses;i++)
|
|
2832 |
{
|
|
2833 |
if (Classes[i].isChecked)
|
|
2834 |
{
|
|
2835 |
hsbs[0]=Classes[i].hsb1;
|
|
2836 |
Nf[0]=Classes[i].N1;
|
|
2837 |
TotalHsbs++;
|
|
2838 |
break;
|
|
2839 |
}
|
|
2840 |
}
|
|
2841 |
for (i=0;i<TotalClasses;i++)
|
|
2842 |
{
|
|
2843 |
if (Classes[i].isChecked)
|
|
2844 |
{
|
|
2845 |
hsbs[TotalHsbs]=Classes[i].hsb2;
|
|
2846 |
Nf[TotalHsbs]=Classes[i].N2;
|
|
2847 |
TotalHsbs++;
|
|
2848 |
}
|
|
2849 |
}
|
|
2850 |
//然后找到距离最近的颜色点;
|
|
2851 |
|
|
2852 |
for (i=0;i<TotalHsbs;i++)
|
|
2853 |
{
|
|
2854 |
distancehsb[i]=CalHSIDistance(hsb1,hsbs[i]);
|
|
2855 |
}
|
|
2856 |
float mindistance;
|
|
2857 |
int mindistanceindex;
|
|
2858 |
mindistance=99999;
|
|
2859 |
mindistanceindex=0;
|
|
2860 |
for (i=0;i<TotalHsbs;i++)
|
|
2861 |
{
|
|
2862 |
if (distancehsb[i]<mindistance)
|
|
2863 |
{
|
|
2864 |
mindistance=distancehsb[i];
|
|
2865 |
mindistanceindex=i;
|
|
2866 |
}
|
|
2867 |
}
|
|
2868 |
//找到距离最近的点,index为i;
|
|
2869 |
//看看最近距离的点是否为边缘点。
|
|
2870 |
if (mindistance>=2.0f)
|
|
2871 |
{
|
|
2872 |
n=-1;
|
|
2873 |
return n;
|
|
2874 |
}
|
|
2875 |
if (mindistanceindex==0)
|
|
2876 |
{ //边缘点,也分落在边缘内和边缘外
|
|
2877 |
k=Calk(hsb1,hsbs[0],hsbs[1]);
|
|
2878 |
if (k<0) //落在边缘点外
|
|
2879 |
{
|
|
2880 |
n=(Nf[1]-Nf[0])*k+Nf[0];
|
|
2881 |
return n;
|
|
2882 |
}
|
|
2883 |
else
|
|
2884 |
{ //落在边缘点内
|
|
2885 |
n=(Nf[1]-Nf[0])*k+Nf[0];
|
|
2886 |
return n;
|
|
2887 |
}
|
|
2888 |
}
|
|
2889 |
else if (mindistanceindex==TotalHsbs-1)
|
|
2890 |
{ //边缘点,也分落在边缘外和边缘内
|
|
2891 |
k=Calk(hsb1,hsbs[mindistanceindex-1],hsbs[mindistanceindex]);
|
|
2892 |
if (k>1) //落在边缘点外
|
|
2893 |
{
|
|
2894 |
n=(Nf[i]-Nf[mindistanceindex-1])*k+Nf[mindistanceindex-1];
|
|
2895 |
return n;
|
|
2896 |
}
|
|
2897 |
else
|
|
2898 |
{ //落在边缘点内
|
|
2899 |
n=(Nf[mindistanceindex]-Nf[mindistanceindex-1])*k+Nf[mindistanceindex-1];
|
|
2900 |
return n;
|
|
2901 |
}
|
|
2902 |
}
|
|
2903 |
else
|
|
2904 |
{ //中间点
|
|
2905 |
//要看靠中间点的哪端
|
|
2906 |
float k1,k2;
|
|
2907 |
float n1,n2;
|
|
2908 |
k1=Calk(hsb1,hsbs[mindistanceindex-1],hsbs[mindistanceindex]);
|
|
2909 |
k2=Calk(hsb1,hsbs[mindistanceindex],hsbs[mindistanceindex+1]);
|
|
2910 |
n1=(Nf[mindistanceindex]-Nf[mindistanceindex-1])*k1+Nf[mindistanceindex-1];
|
|
2911 |
n2=(Nf[mindistanceindex+1]-Nf[mindistanceindex])*k2+Nf[mindistanceindex];
|
|
2912 |
if (k1<=1&&k2<0) //处于一侧点。
|
|
2913 |
{
|
|
2914 |
n=n1;
|
|
2915 |
return n;
|
|
2916 |
}
|
|
2917 |
if (k1>1&&k2<0) //处于两点之间,外弯
|
|
2918 |
{
|
|
2919 |
n=Nf[i];
|
|
2920 |
return n;
|
|
2921 |
}
|
|
2922 |
if (k1<=1&&k2>=0) //处于两点之间,内弯
|
|
2923 |
{
|
|
2924 |
n=(n1+n2)/2;
|
|
2925 |
return n;
|
|
2926 |
}
|
|
2927 |
if (k1>=1&&k2>=0) //处于另一侧点
|
|
2928 |
{
|
|
2929 |
n=n2;
|
|
2930 |
return n;
|
|
2931 |
}
|
|
2932 |
|
|
2933 |
}
|
|
2934 |
for (i=0;i<TotalClasses;i++)
|
|
2935 |
{
|
|
2936 |
if (!Classes[i].isChecked) {continue;}
|
|
2937 |
chsb1=Classes[i].hsb1;
|
|
2938 |
chsb2=Classes[i].hsb2;
|
|
2939 |
kPosition[i]=Calk(hsb1,chsb1,chsb2);
|
|
2940 |
lastCheckedClass=i;
|
|
2941 |
}
|
|
2942 |
for (i=0;i<lastCheckedClass;i++)
|
|
2943 |
{
|
|
2944 |
if (!Classes[i].isChecked) {continue;}
|
|
2945 |
if (kPosition[i]<0) {n=kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i].N1;;break;}
|
|
2946 |
if (i==lastCheckedClass-1) {n=kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i].N1;break;}
|
|
2947 |
if (kPosition[i]>=0&&kPosition[i]<=1&&kPosition[i+1]<0) {n=kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i].N1;break;}
|
|
2948 |
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;}
|
|
2949 |
if (kPosition[i]>1&&kPosition[i+1]<0)
|
|
2950 |
{
|
|
2951 |
n=Classes[i].N2;break;
|
|
2952 |
}
|
|
2953 |
}
|
|
2954 |
return n;
|
|
2955 |
}
|
|
2956 |
*/
|
|
2957 |
/*
|
|
2958 |
for (i=0;i<pt1total-1;i++) //验证所有的点是不是都在一条线上。
|
|
2959 |
{
|
|
2960 |
startpt1=i;
|
|
2961 |
pt1valid[i]=1;
|
|
2962 |
continuepts1=2; //在一条线上的点的数量,最开始的两个点肯定在同一条线上。
|
|
2963 |
|
|
2964 |
for (j=i+1;j<pt1total;j++)
|
|
2965 |
{
|
|
2966 |
|
|
2967 |
continuepts1=2; //在一条线上的点的数量,最开始的两个点肯定在同一条线上。
|
|
2968 |
pt1valid[j]=1;
|
|
2969 |
angle1=atan(((double)pt1[i].x-pt1[j].x)/((double)pt1[i].y-pt1[j].y));
|
|
2970 |
endpt1=j;
|
|
2971 |
for (k=j+1;k<pt1total;k++)
|
|
2972 |
{
|
|
2973 |
|
|
2974 |
angle2=atan(((double)pt1[i].x-pt1[k].x)/((double)pt1[i].y-pt1[k].y));
|
|
2975 |
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));
|
|
2976 |
intercept=distance*sin(abs(angle2-angle1));
|
|
2977 |
//离开直线的距离,截距;
|
|
2978 |
//if (abs(angle1-angle2)<maxangle) //如果与第一个点的角度和原来的角度在一定范围内,认为在一条线上。
|
|
2979 |
if (intercept<maxintercept)
|
|
2980 |
{
|
|
2981 |
pt1valid[k]=1;
|
|
2982 |
endpt1=k;
|
|
2983 |
continuepts1++;
|
|
2984 |
}
|
|
2985 |
else
|
|
2986 |
{
|
|
2987 |
pt1valid[k]=0;
|
|
2988 |
}
|
|
2989 |
}
|
|
2990 |
|
|
2991 |
if (continuepts1>=4) //如果在3个点或以上在同一条线上,认为是一条有效的线。
|
|
2992 |
{
|
|
2993 |
line1found=1;
|
|
2994 |
break;
|
|
2995 |
}
|
|
2996 |
else //否则重新找线。
|
|
2997 |
{
|
|
2998 |
pt1valid[j]=0;
|
|
2999 |
for (k=j+1;k<pt1total;k++)
|
|
3000 |
{
|
|
3001 |
pt1valid[k]=0;
|
|
3002 |
}
|
|
3003 |
}
|
|
3004 |
}
|
|
3005 |
if (line1found) {break;}
|
|
3006 |
pt1valid[i]=0;
|
|
3007 |
}
|
|
3008 |
*/
|
|
3009 |
int BayerGR8toRGB32(void * src,void * dest,int width,int height,int stride1,int stride2)
|
|
3010 |
{
|
|
3011 |
int w=width,h=height;
|
|
3012 |
// unsigned char * srcpixel=(unsigned char *)srcbuf;
|
|
3013 |
// DWORD * pixels=(DWORD *)destbuf;
|
|
3014 |
|
|
3015 |
|
|
3016 |
//unsigned short R,G,B,R1,R2,R3,R4,G1,G2,G3,G4,B1,B2,B3,B4;
|
|
3017 |
|
|
3018 |
|
|
3019 |
DWORD * destbuf=(DWORD *) dest;
|
|
3020 |
unsigned char * srcbuf=(unsigned char *)src;
|
|
3021 |
// s=width;
|
|
3022 |
DWORD w2=stride2/4;
|
|
3023 |
|
|
3024 |
|
|
3025 |
#pragma omp parallel for
|
|
3026 |
for (int i=2;i<height-4;i+=2)
|
|
3027 |
{
|
|
3028 |
unsigned char G00, B01, G02, B03, G04, B05;
|
|
3029 |
unsigned char R10, G11, R12, G13, R14, G15;
|
|
3030 |
unsigned char G20, B21, G22, B23, G24, B25;
|
|
3031 |
unsigned char R30, G31, R32, G33, R34, G35;
|
|
3032 |
unsigned char G40, B41, G42, B43, G44, B45;
|
|
3033 |
unsigned char R50, G51, R52, G53, R54, G55;
|
|
3034 |
|
|
3035 |
COLOR pixel;
|
|
3036 |
unsigned char *line0=srcbuf+i*stride1-stride1-stride1;
|
|
3037 |
unsigned char *line1=srcbuf+i*stride1-stride1;
|
|
3038 |
unsigned char *line2=srcbuf+i*stride1;
|
|
3039 |
unsigned char *line3=srcbuf+i*stride1+stride1;
|
|
3040 |
unsigned char *line4=srcbuf+i*stride1+stride1+stride1;
|
|
3041 |
unsigned char *line5=srcbuf+i*stride1+stride1+stride1+stride1;
|
|
3042 |
int ll=i*w2;
|
|
3043 |
int lll=i*w2+w2;
|
|
3044 |
for (int j=2;j<width-4;j+=2)
|
|
3045 |
{
|
|
3046 |
// 奇数行
|
|
3047 |
|
|
3048 |
pixel.R=(line2[j-1]+line2[j+1])/2;
|
|
3049 |
pixel.G=line2[j];
|
|
3050 |
pixel.B=(line1[j]+line3[j])/2;
|
|
3051 |
((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
|
|
3052 |
|
|
3053 |
pixel.R=line2[j+1];
|
|
3054 |
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
|
3055 |
//else{pixel.G=(G22+G24)/2;}
|
|
3056 |
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; }
|
|
3057 |
else { pixel.G=(line2[j]+line2[j+2])/2; }
|
|
3058 |
|
|
3059 |
pixel.B=((unsigned int )line1[j]+line3[j]+line1[j+2]+line3[j+2])/4;
|
|
3060 |
destbuf[ll+j+1]=pixel.argb ;
|
|
3061 |
|
|
3062 |
//偶数行
|
|
3063 |
pixel.R=((unsigned int )line2[j-1]+line4[j-1]+line2[j+1]+line4[j+1])/4;
|
|
3064 |
// if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
|
3065 |
// else{pixel.G=(G31+G33)/2;}
|
|
3066 |
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; }
|
|
3067 |
else { pixel.G=(line3[j-1]+line3[j+1])/2; }
|
|
3068 |
pixel.B=line3[j];
|
|
3069 |
destbuf[lll+j]=pixel.argb ;
|
|
3070 |
|
|
3071 |
pixel.R=(line2[j+1]+line4[j+1])/2;
|
|
3072 |
pixel.G=line3[j+1];
|
|
3073 |
pixel.B=(line3[j]+line3[j+2])/2;
|
|
3074 |
destbuf[lll+j+1]=pixel.argb ;
|
|
3075 |
}
|
|
3076 |
|
|
3077 |
continue;
|
|
3078 |
|
|
3079 |
int k,l,m,n,p,q;//,s;
|
|
3080 |
|
|
3081 |
k=i*stride1-stride1-stride1; //上一行
|
|
3082 |
l=i*stride1-stride1; //当前行
|
|
3083 |
m=i*stride1; //下一行
|
|
3084 |
n=m+stride1; //下两行
|
|
3085 |
p=m+stride1+stride1;
|
|
3086 |
q=m+stride1+stride1+stride1;
|
|
3087 |
B01=srcbuf[k+1];G02=srcbuf[k+2];B03=srcbuf[k+3];G04=srcbuf[k+4];B05=srcbuf[k+5];
|
|
3088 |
R10=srcbuf[l+0];G11=srcbuf[l+1];R12=srcbuf[l+2];G13=srcbuf[l+3];R14=srcbuf[l+4];G15=srcbuf[l+5];
|
|
3089 |
G20=srcbuf[m+0];B21=srcbuf[m+1];G22=srcbuf[m+2];B23=srcbuf[m+3];G24=srcbuf[m+4];B25=srcbuf[m+5];
|
|
3090 |
R30=srcbuf[n+0];G31=srcbuf[n+1];R32=srcbuf[n+2];G33=srcbuf[n+3];R34=srcbuf[n+4];G35=srcbuf[n+5];
|
|
3091 |
G40=srcbuf[p+0];B41=srcbuf[p+1];G42=srcbuf[p+2];B43=srcbuf[p+3];G44=srcbuf[p+4];B45=srcbuf[p+5];
|
|
3092 |
R50=srcbuf[q+0];G51=srcbuf[q+1];R52=srcbuf[q+2];G53=srcbuf[q+3];R54=srcbuf[q+4];G55=srcbuf[q+5];
|
|
3093 |
|
|
3094 |
for (int j=2;j<width-4;j+=2)
|
|
3095 |
{
|
|
3096 |
// 奇数行
|
|
3097 |
|
|
3098 |
/*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];
|
|
3099 |
/*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];
|
|
3100 |
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];
|
|
3101 |
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];
|
|
3102 |
/*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];
|
|
3103 |
/*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];
|
|
3104 |
|
|
3105 |
pixel.R=(B21+B23)/2;
|
|
3106 |
pixel.G=G22;
|
|
3107 |
pixel.B=(R12+R32)/2;
|
|
3108 |
((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
|
|
3109 |
|
|
3110 |
pixel.R=B23;
|
|
3111 |
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
|
3112 |
//else{pixel.G=(G22+G24)/2;}
|
|
3113 |
if (abs(signed(B03+B43-B23*2))<abs(signed(B21+B25-B23*2))) { pixel.G=(G13+G33)/2; }
|
|
3114 |
else { pixel.G=(G22+G24)/2; }
|
|
3115 |
|
|
3116 |
pixel.B=((unsigned int )R12+R32+R14+R34)/4;
|
|
3117 |
destbuf[i*w2+j+1]=pixel.argb ;
|
|
3118 |
|
|
3119 |
//偶数行
|
|
3120 |
pixel.R=((unsigned int )B21+B41+B23+B43)/4;
|
|
3121 |
// if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
|
3122 |
// else{pixel.G=(G31+G33)/2;}
|
|
3123 |
if (abs(signed(R12+R52-R32*2))<abs(signed(R30+R34-R32*2))) { pixel.G=(G22+G42)/2; }
|
|
3124 |
else { pixel.G=(G31+G33)/2; }
|
|
3125 |
pixel.B=R32;
|
|
3126 |
destbuf[i*w2+w2+j]=pixel.argb ;
|
|
3127 |
|
|
3128 |
pixel.R=(B23+B43)/2;
|
|
3129 |
pixel.G=G33;
|
|
3130 |
pixel.B=(R32+R34)/2;
|
|
3131 |
destbuf[i*w2+w2+j+1]=pixel.argb ;
|
|
3132 |
}
|
|
3133 |
}
|
|
3134 |
return 0;
|
|
3135 |
|
|
3136 |
/*
|
|
3137 |
|
|
3138 |
for (int i=0;i<h;i+=2)
|
|
3139 |
{
|
|
3140 |
COLOR c1;
|
|
3141 |
int k=i*(int)stride1;
|
|
3142 |
//偶数行
|
|
3143 |
int l=i*stride2/4;
|
|
3144 |
for (int j=0;j<w;j+=2)
|
|
3145 |
{
|
|
3146 |
c1.G=srcpixel[k+j];
|
|
3147 |
c1.B=srcpixel[k+j+1];
|
|
3148 |
c1.R=srcpixel[k+stride1+j];
|
|
3149 |
pixels[l+j]=c1.argb;
|
|
3150 |
pixels[l+j+1]=c1.argb;
|
|
3151 |
}
|
|
3152 |
//奇数行
|
|
3153 |
l=(i+1)*stride2/4;
|
|
3154 |
for (int j=0;j<w;j+=2)
|
|
3155 |
{
|
|
3156 |
c1.G=srcpixel[k+stride1+j+1];
|
|
3157 |
c1.B=srcpixel[k+j+1];
|
|
3158 |
c1.R=srcpixel[k+stride1+j];
|
|
3159 |
pixels[l+j]=c1.argb;
|
|
3160 |
pixels[l+j+1]=c1.argb;
|
|
3161 |
}
|
|
3162 |
}
|
|
3163 |
return 1;
|
|
3164 |
*/
|
|
3165 |
}
|
|
3166 |
int BayerGB8toRGB32(void * src,void * dest,int width,int height,int stride1,int stride2)
|
|
3167 |
{
|
|
3168 |
int w=width,h=height;
|
|
3169 |
// unsigned char * srcpixel=(unsigned char *)srcbuf;
|
|
3170 |
// DWORD * pixels=(DWORD *)destbuf;
|
|
3171 |
|
|
3172 |
|
|
3173 |
//unsigned short R,G,B,R1,R2,R3,R4,G1,G2,G3,G4,B1,B2,B3,B4;
|
|
3174 |
|
|
3175 |
|
|
3176 |
DWORD * destbuf=(DWORD *) dest;
|
|
3177 |
unsigned char * srcbuf=(unsigned char *)src;
|
|
3178 |
// s=width;
|
|
3179 |
DWORD w2=stride2/4;
|
|
3180 |
|
|
3181 |
|
|
3182 |
#pragma omp parallel for
|
|
3183 |
for (int i=2;i<height-4;i+=2)
|
|
3184 |
{
|
|
3185 |
unsigned char G00, B01, G02, B03, G04, B05;
|
|
3186 |
unsigned char R10, G11, R12, G13, R14, G15;
|
|
3187 |
unsigned char G20, B21, G22, B23, G24, B25;
|
|
3188 |
unsigned char R30, G31, R32, G33, R34, G35;
|
|
3189 |
unsigned char G40, B41, G42, B43, G44, B45;
|
|
3190 |
unsigned char R50, G51, R52, G53, R54, G55;
|
|
3191 |
|
|
3192 |
COLOR pixel;
|
|
3193 |
unsigned char *line0=srcbuf+i*stride1-stride1-stride1;
|
|
3194 |
unsigned char *line1=srcbuf+i*stride1-stride1;
|
|
3195 |
unsigned char *line2=srcbuf+i*stride1;
|
|
3196 |
unsigned char *line3=srcbuf+i*stride1+stride1;
|
|
3197 |
unsigned char *line4=srcbuf+i*stride1+stride1+stride1;
|
|
3198 |
unsigned char *line5=srcbuf+i*stride1+stride1+stride1+stride1;
|
|
3199 |
|
|
3200 |
for (int j=2;j<width-4;j+=2)
|
|
3201 |
{
|
|
3202 |
// 奇数行
|
|
3203 |
|
|
3204 |
pixel.B=(line2[j-1]+line2[j+1])/2;
|
|
3205 |
pixel.G=line2[j];
|
|
3206 |
pixel.R=(line1[j]+line3[j])/2;
|
|
3207 |
((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
|
|
3208 |
|
|
3209 |
pixel.B=line2[j+1];
|
|
3210 |
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
|
3211 |
//else{pixel.G=(G22+G24)/2;}
|
|
3212 |
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; }
|
|
3213 |
else { pixel.G=(line2[j]+line2[j+2])/2; }
|
|
3214 |
|
|
3215 |
pixel.R=((unsigned int )line1[j]+line3[j]+line1[j+2]+line3[j+2])/4;
|
|
3216 |
destbuf[i*w2+j+1]=pixel.argb ;
|
|
3217 |
|
|
3218 |
//偶数行
|
|
3219 |
pixel.B=((unsigned int )line2[j-1]+line4[j-1]+line2[j+1]+line4[j+1])/4;
|
|
3220 |
// if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
|
3221 |
// else{pixel.G=(G31+G33)/2;}
|
|
3222 |
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; }
|
|
3223 |
else { pixel.G=(line3[j-1]+line3[j+1])/2; }
|
|
3224 |
pixel.R=line3[j];
|
|
3225 |
destbuf[i*w2+w2+j]=pixel.argb ;
|
|
3226 |
|
|
3227 |
pixel.B=(line2[j+1]+line4[j+1])/2;
|
|
3228 |
pixel.G=line3[j+1];
|
|
3229 |
pixel.R=(line3[j]+line3[j+2])/2;
|
|
3230 |
destbuf[i*w2+w2+j+1]=pixel.argb ;
|
|
3231 |
}
|
|
3232 |
|
|
3233 |
continue;
|
|
3234 |
|
|
3235 |
int k,l,m,n,p,q;//,s;
|
|
3236 |
|
|
3237 |
k=i*stride1-stride1-stride1; //上一行
|
|
3238 |
l=i*stride1-stride1; //当前行
|
|
3239 |
m=i*stride1; //下一行
|
|
3240 |
n=m+stride1; //下两行
|
|
3241 |
p=m+stride1+stride1;
|
|
3242 |
q=m+stride1+stride1+stride1;
|
|
3243 |
B01=srcbuf[k+1];G02=srcbuf[k+2];B03=srcbuf[k+3];G04=srcbuf[k+4];B05=srcbuf[k+5];
|
|
3244 |
R10=srcbuf[l+0];G11=srcbuf[l+1];R12=srcbuf[l+2];G13=srcbuf[l+3];R14=srcbuf[l+4];G15=srcbuf[l+5];
|
|
3245 |
G20=srcbuf[m+0];B21=srcbuf[m+1];G22=srcbuf[m+2];B23=srcbuf[m+3];G24=srcbuf[m+4];B25=srcbuf[m+5];
|
|
3246 |
R30=srcbuf[n+0];G31=srcbuf[n+1];R32=srcbuf[n+2];G33=srcbuf[n+3];R34=srcbuf[n+4];G35=srcbuf[n+5];
|
|
3247 |
G40=srcbuf[p+0];B41=srcbuf[p+1];G42=srcbuf[p+2];B43=srcbuf[p+3];G44=srcbuf[p+4];B45=srcbuf[p+5];
|
|
3248 |
R50=srcbuf[q+0];G51=srcbuf[q+1];R52=srcbuf[q+2];G53=srcbuf[q+3];R54=srcbuf[q+4];G55=srcbuf[q+5];
|
|
3249 |
|
|
3250 |
for (int j=2;j<width-4;j+=2)
|
|
3251 |
{
|
|
3252 |
// 奇数行
|
|
3253 |
|
|
3254 |
/*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];
|
|
3255 |
/*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];
|
|
3256 |
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];
|
|
3257 |
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];
|
|
3258 |
/*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];
|
|
3259 |
/*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];
|
|
3260 |
|
|
3261 |
pixel.B=(B21+B23)/2;
|
|
3262 |
pixel.G=G22;
|
|
3263 |
pixel.R=(R12+R32)/2;
|
|
3264 |
((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
|
|
3265 |
|
|
3266 |
pixel.B=B23;
|
|
3267 |
//if (abs(signed(B03-B43))<abs(signed(B21-B25))) {pixel.G=(G13+G33)/2;}
|
|
3268 |
//else{pixel.G=(G22+G24)/2;}
|
|
3269 |
if (abs(signed(B03+B43-B23*2))<abs(signed(B21+B25-B23*2))) { pixel.G=(G13+G33)/2; }
|
|
3270 |
else { pixel.G=(G22+G24)/2; }
|
|
3271 |
|
|
3272 |
pixel.R=((unsigned int )R12+R32+R14+R34)/4;
|
|
3273 |
destbuf[i*w2+j+1]=pixel.argb ;
|
|
3274 |
|
|
3275 |
//偶数行
|
|
3276 |
pixel.B=((unsigned int )B21+B41+B23+B43)/4;
|
|
3277 |
// if (abs(signed(R12-R52))<abs(signed(R30-R34))) { pixel.G=(G22+G42)/2;}
|
|
3278 |
// else{pixel.G=(G31+G33)/2;}
|
|
3279 |
if (abs(signed(R12+R52-R32*2))<abs(signed(R30+R34-R32*2))) { pixel.G=(G22+G42)/2; }
|
|
3280 |
else { pixel.G=(G31+G33)/2; }
|
|
3281 |
pixel.R=R32;
|
|
3282 |
destbuf[i*w2+w2+j]=pixel.argb ;
|
|
3283 |
|
|
3284 |
pixel.B=(B23+B43)/2;
|
|
3285 |
pixel.G=G33;
|
|
3286 |
pixel.R=(R32+R34)/2;
|
|
3287 |
destbuf[i*w2+w2+j+1]=pixel.argb ;
|
|
3288 |
}
|
|
3289 |
}
|
|
3290 |
return 0;
|
|
3291 |
|
|
3292 |
/*
|
|
3293 |
|
|
3294 |
for (int i=0;i<h;i+=2)
|
|
3295 |
{
|
|
3296 |
COLOR c1;
|
|
3297 |
int k=i*(int)stride1;
|
|
3298 |
//偶数行
|
|
3299 |
int l=i*stride2/4;
|
|
3300 |
for (int j=0;j<w;j+=2)
|
|
3301 |
{
|
|
3302 |
c1.G=srcpixel[k+j];
|
|
3303 |
c1.B=srcpixel[k+j+1];
|
|
3304 |
c1.R=srcpixel[k+stride1+j];
|
|
3305 |
pixels[l+j]=c1.argb;
|
|
3306 |
pixels[l+j+1]=c1.argb;
|
|
3307 |
}
|
|
3308 |
//奇数行
|
|
3309 |
l=(i+1)*stride2/4;
|
|
3310 |
for (int j=0;j<w;j+=2)
|
|
3311 |
{
|
|
3312 |
c1.G=srcpixel[k+stride1+j+1];
|
|
3313 |
c1.B=srcpixel[k+j+1];
|
|
3314 |
c1.R=srcpixel[k+stride1+j];
|
|
3315 |
pixels[l+j]=c1.argb;
|
|
3316 |
pixels[l+j+1]=c1.argb;
|
|
3317 |
}
|
|
3318 |
}
|
|
3319 |
return 1;
|
|
3320 |
*/
|
|
3321 |
}
|
|
3322 |
int BayerGB8toRGB24(void * srcbuf,void * destbuf,int width,int height,int stride,int stride2)
|
|
3323 |
{
|
|
3324 |
int w=width,h=height;
|
|
3325 |
int Stride=stride;
|
|
3326 |
int s=stride2;
|
|
3327 |
unsigned char * srcpixel=(unsigned char *)srcbuf;
|
|
3328 |
unsigned char * pixels=(unsigned char *)destbuf;
|
|
3329 |
|
|
3330 |
#pragma omp parallel for
|
|
3331 |
for (int i=0;i<h;i+=2)
|
|
3332 |
{
|
|
3333 |
COLOR c1;
|
|
3334 |
int k=i*(int)Stride;
|
|
3335 |
//偶数行
|
|
3336 |
int l=i*s;
|
|
3337 |
for (int j=0;j<w;j+=2)
|
|
3338 |
{
|
|
3339 |
c1.G=srcpixel[k+j];
|
|
3340 |
c1.B=srcpixel[k+j+1];
|
|
3341 |
c1.R=srcpixel[k+Stride+j];
|
|
3342 |
pixels[l+(j)*3+0]=c1.B; pixels[l+(j)*3+1]=c1.G; pixels[l+(j)*3+2]=c1.R;
|
|
3343 |
pixels[l+(j+1)*3+0]=c1.B; pixels[l+(j+1)*3+1]=c1.G; pixels[l+(j+1)*3+2]=c1.R;
|
|
3344 |
}
|
|
3345 |
//奇数行
|
|
3346 |
l=(i+1)*s;
|
|
3347 |
for (int j=0;j<w;j+=2)
|
|
3348 |
{
|
|
3349 |
c1.G=srcpixel[k+Stride+j+1];
|
|
3350 |
c1.B=srcpixel[k+j+1];
|
|
3351 |
c1.R=srcpixel[k+Stride+j];
|
|
3352 |
pixels[l+(j)*3+0]=c1.B; pixels[l+(j)*3+1]=c1.G; pixels[l+(j)*3+2]=c1.R;
|
|
3353 |
pixels[l+(j+1)*3+0]=c1.B; pixels[l+(j+1)*3+1]=c1.G; pixels[l+(j+1)*3+2]=c1.R;
|
|
3354 |
}
|
|
3355 |
}
|
|
3356 |
return 1;
|
|
3357 |
}
|
|
3358 |
|
|
3359 |
int SecWhiteBalance::LoadWBParamFromFile(CString sFilePathName)
|
|
3360 |
{
|
|
3361 |
CString s1;
|
|
3362 |
// s1.Format(_T("从文件 %s 加载白平衡矫正模板 \r\n"),sFilePathName);
|
|
3363 |
// SysLog(s1);
|
|
3364 |
int j=0;
|
|
3365 |
Gdiplus::Bitmap bitmap1(sFilePathName);
|
|
3366 |
|
|
3367 |
if (bitmap1.GetWidth()!=0)
|
|
3368 |
{j=ReadWBParamFromBmp(&bitmap1);}
|
|
3369 |
return j;
|
|
3370 |
}
|
|
3371 |
|
|
3372 |
int SecWhiteBalance::ReadWBParamFromBmp(Gdiplus::Bitmap * bitmap1)
|
|
3373 |
{
|
|
3374 |
|
|
3375 |
// double tick0=GetTickCountmS();
|
|
3376 |
if (bitmap1==NULL) {return 0;}
|
|
3377 |
if (bitmap1->GetWidth()==0||bitmap1->GetHeight()==0) {return 0;}
|
|
3378 |
int i,j,k;
|
|
3379 |
int w,h;
|
|
3380 |
w=bitmap1->GetWidth();
|
|
3381 |
h=bitmap1->GetHeight();
|
|
3382 |
if (0==w||0==h)
|
|
3383 |
{return 0;}
|
|
3384 |
|
|
3385 |
Gdiplus::BitmapData bitmapdata0;
|
|
3386 |
UINT * pixels;
|
|
3387 |
Gdiplus::Rect rect0(0,0,w,h);
|
|
3388 |
|
|
3389 |
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapdata0);
|
|
3390 |
if (GdipStatus!=Gdiplus::Ok)
|
|
3391 |
{
|
|
3392 |
CString Errs1;
|
|
3393 |
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
|
3394 |
// SysLog(Errs1);
|
|
3395 |
return 0;
|
|
3396 |
}
|
|
3397 |
pixels=(UINT *)bitmapdata0.Scan0 ;
|
|
3398 |
|
|
3399 |
// xsecs=w/xstep;
|
|
3400 |
// ysecs=h/ystep;
|
|
3401 |
// int m,n;
|
|
3402 |
COLOR c1;
|
|
3403 |
// int secR,secG,secB,secV;
|
|
3404 |
// float aveR,aveG,aveB,aveV;
|
|
3405 |
float totalaveR,totalaveG,totalaveB;
|
|
3406 |
totalaveR=0;totalaveG=0;totalaveB=0;
|
|
3407 |
for (i=0;i<wbysecs;i++)
|
|
3408 |
{
|
|
3409 |
for (j=0;j<wbxsecs;j++)
|
|
3410 |
{
|
|
3411 |
wbsectotalR[i][j]=0;
|
|
3412 |
wbsectotalG[i][j]=0;
|
|
3413 |
wbsectotalB[i][j]=0;
|
|
3414 |
wbsecsamples[i][j]=0;
|
|
3415 |
}
|
|
3416 |
}
|
|
3417 |
int xsec,ysec;
|
|
3418 |
for (i=0;i<h;i++)
|
|
3419 |
{
|
|
3420 |
k=i*w;
|
|
3421 |
ysec=i*wbysecs/h;
|
|
3422 |
for (j=0;j<w;j++)
|
|
3423 |
{
|
|
3424 |
xsec=j*wbxsecs/w;
|
|
3425 |
c1.argb =pixels[k+j];
|
|
3426 |
wbsectotalR[ysec][xsec]+=c1.R;
|
|
3427 |
wbsectotalG[ysec][xsec]+=c1.G;
|
|
3428 |
wbsectotalB[ysec][xsec]+=c1.B;
|
|
3429 |
wbsecsamples[ysec][xsec]++;
|
|
3430 |
}
|
|
3431 |
}
|
|
3432 |
float wbV;
|
|
3433 |
wbtotalV=0;
|
|
3434 |
for (i=0;i<wbysecs;i++)
|
|
3435 |
{
|
|
3436 |
for (j=0;j<wbxsecs;j++)
|
|
3437 |
{
|
|
3438 |
wbsecR[i][j]=(float)wbsectotalR[i][j]/wbsecsamples[i][j];
|
|
3439 |
wbsecG[i][j]=(float)wbsectotalG[i][j]/wbsecsamples[i][j];
|
|
3440 |
wbsecB[i][j]=(float)wbsectotalB[i][j]/wbsecsamples[i][j];
|
|
3441 |
//wbV=wbsecR[i][j]*0.299f+wbsecG[i][j]*0.587f+wbsecB[i][j]*0.114f;
|
|
3442 |
wbV=RGBtoVf(wbsecR[i][j],wbsecG[i][j],wbsecB[i][j]);
|
|
3443 |
wbtotalV+=wbV;
|
|
3444 |
}
|
|
3445 |
}
|
|
3446 |
wbaveV=wbtotalV/(wbysecs*wbxsecs);
|
|
3447 |
// wbaveV=128.0f;
|
|
3448 |
/*
|
|
3449 |
for (i=0;i<ysecs;i++)
|
|
3450 |
{ yoff=i*ystep*w;
|
|
3451 |
for (j=0;j<xsecs;j++)
|
|
3452 |
{
|
|
3453 |
xoff=j*xstep;
|
|
3454 |
secV=0;
|
|
3455 |
secR=0;secG=0;secB=0;
|
|
3456 |
for(k=0;k<ystep;k++)
|
|
3457 |
{
|
|
3458 |
m=yoff+k*w;
|
|
3459 |
for (l=0;l<xstep;l++)
|
|
3460 |
{
|
|
3461 |
secR+=c1.R ;
|
|
3462 |
secG+=c1.G;
|
|
3463 |
secB+=c1.B;
|
|
3464 |
}
|
|
3465 |
}
|
|
3466 |
aveR=(float)secR/(xstep*ystep);
|
|
3467 |
aveG=(float)secG/(xstep*ystep);
|
|
3468 |
aveB=(float)secB/(xstep*ystep);
|
|
3469 |
|
|
3470 |
aveV=secV/(xstep*ystep);
|
|
3471 |
bright[i][j]=aveV;
|
|
3472 |
wbR[i][j]=aveR;
|
|
3473 |
wbG[i][j]=aveG;
|
|
3474 |
wbB[i][j]=aveB;
|
|
3475 |
totalaveR+=aveR;
|
|
3476 |
totalaveG+=aveG;
|
|
3477 |
totalaveB+=aveB;
|
|
3478 |
}
|
|
3479 |
}
|
|
3480 |
//*/
|
|
3481 |
bitmap1->UnlockBits(&bitmapdata0);
|
|
3482 |
// double tick1=GetTickCountmS();
|
|
3483 |
|
|
3484 |
CString s1;
|
|
3485 |
// s1.Format(_T("创建白平衡数组,w,h %d %d 用时 %.2fmS\r\n"),w,h,tick1-tick0);
|
|
3486 |
// SysLog(s1);
|
|
3487 |
wbcorrloaded=1;
|
|
3488 |
autowbcorronopen=1;
|
|
3489 |
|
|
3490 |
// ((CButton *)GetDlgItem(IDC_CHECK_WBCORR))->SetCheck(true);
|
|
3491 |
|
|
3492 |
return 1;
|
|
3493 |
}
|
|
3494 |
|
|
3495 |
int SecWhiteBalance::LoadBayerWBParamFromFile(CString sFilePathName)
|
|
3496 |
{
|
|
3497 |
CString s1;
|
|
3498 |
// s1.Format(_T("从文件 %s 加载白平衡矫正模板 \r\n"),sFilePathName);
|
|
3499 |
// SysLog(s1);
|
|
3500 |
int j=0;
|
|
3501 |
Gdiplus::Bitmap bitmap1(sFilePathName);
|
|
3502 |
|
|
3503 |
if (bitmap1.GetWidth()!=0)
|
|
3504 |
{j=ReadBayerWBParamFromBmp(&bitmap1);}
|
|
3505 |
return j;
|
|
3506 |
}
|
|
3507 |
int SecWhiteBalance::ReadBayerWBParamFromBmp(Gdiplus::Bitmap * bitmap1)
|
|
3508 |
{
|
|
3509 |
|
|
3510 |
// double tick0=GetTickCountmS();
|
|
3511 |
if (bitmap1==NULL) {return 0;}
|
|
3512 |
if (bitmap1->GetWidth()==0||bitmap1->GetHeight()==0) {return 0;}
|
|
3513 |
int i,j,k;
|
|
3514 |
int w,h;
|
|
3515 |
w=bitmap1->GetWidth();
|
|
3516 |
h=bitmap1->GetHeight();
|
|
3517 |
if (0==w||0==h)
|
|
3518 |
{return 0;}
|
|
3519 |
|
|
3520 |
Gdiplus::BitmapData bitmapdata0;
|
|
3521 |
unsigned char * pixels;
|
|
3522 |
Gdiplus::Rect rect0(0,0,w,h);
|
|
3523 |
|
|
3524 |
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat8bppIndexed,&bitmapdata0);
|
|
3525 |
if (GdipStatus!=Gdiplus::Ok)
|
|
3526 |
{
|
|
3527 |
CString Errs1;
|
|
3528 |
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
|
3529 |
// SysLog(Errs1);
|
|
3530 |
return 0;
|
|
3531 |
}
|
|
3532 |
pixels=(unsigned char *)bitmapdata0.Scan0 ;
|
|
3533 |
int stride=bitmapdata0.Stride;
|
|
3534 |
// xsecs=w/xstep;
|
|
3535 |
// ysecs=h/ystep;
|
|
3536 |
// int m,n;
|
|
3537 |
//COLOR c1;
|
|
3538 |
|
|
3539 |
// int secR,secG,secB,secV;
|
|
3540 |
// float aveR,aveG,aveB,aveV;
|
|
3541 |
float totalaveR,totalaveG,totalaveB;
|
|
3542 |
totalaveR=0;totalaveG=0;totalaveB=0;
|
|
3543 |
for (i=0;i<wbysecs;i++)
|
|
3544 |
{
|
|
3545 |
for (j=0;j<wbxsecs;j++)
|
|
3546 |
{
|
|
3547 |
wbsectotalR[i][j]=0;
|
|
3548 |
wbsectotalG[i][j]=0;
|
|
3549 |
wbsectotalB[i][j]=0;
|
|
3550 |
wbsecsamples[i][j]=0;
|
|
3551 |
}
|
|
3552 |
}
|
|
3553 |
int xsec,ysec;
|
|
3554 |
for (i=0;i<h;i+=2)
|
|
3555 |
{
|
|
3556 |
k=i*stride;
|
|
3557 |
ysec=i*wbysecs/h;
|
|
3558 |
for (j=0;j<w;j+=2)
|
|
3559 |
{
|
|
3560 |
xsec=j*wbxsecs/w;
|
|
3561 |
unsigned char c1,c2,c3,c4;
|
|
3562 |
c1 = pixels[k+j];
|
|
3563 |
c2 = pixels[k+j+1];
|
|
3564 |
c3 = pixels[k+stride+j];
|
|
3565 |
c4 = pixels[k+stride+j+1];
|
|
3566 |
|
|
3567 |
wbsectotalG[ysec][xsec]+=c1;
|
|
3568 |
wbsectotalR[ysec][xsec]+=c2;
|
|
3569 |
wbsectotalB[ysec][xsec]+=c3;
|
|
3570 |
wbsectotalG2[ysec][xsec]+=c4;
|
|
3571 |
wbsecsamples[ysec][xsec]++;
|
|
3572 |
}
|
|
3573 |
}
|
|
3574 |
bitmap1->UnlockBits(&bitmapdata0);
|
|
3575 |
float wbV;
|
|
3576 |
wbtotalV=0;
|
|
3577 |
for (i=0;i<wbysecs;i++)
|
|
3578 |
{
|
|
3579 |
for (j=0;j<wbxsecs;j++)
|
|
3580 |
{
|
|
3581 |
wbsecR[i][j]=(float)wbsectotalR[i][j]/wbsecsamples[i][j];
|
|
3582 |
wbsecG[i][j]=(float)wbsectotalG[i][j]/wbsecsamples[i][j];
|
|
3583 |
wbsecB[i][j]=(float)wbsectotalB[i][j]/wbsecsamples[i][j];
|
|
3584 |
wbsecG2[i][j]=(float)wbsectotalG2[i][j]/wbsecsamples[i][j];
|
|
3585 |
//wbV=wbsecR[i][j]*0.299f+wbsecG[i][j]*0.587f+wbsecB[i][j]*0.114f;
|
|
3586 |
wbV=RGBtoVf(wbsecR[i][j],wbsecG[i][j],wbsecB[i][j]);
|
|
3587 |
wbtotalV+=wbV;
|
|
3588 |
}
|
|
3589 |
}
|
|
3590 |
wbaveV=wbtotalV/(wbysecs*wbxsecs);
|
|
3591 |
/* 保存成一个BMP
|
|
3592 |
Bitmap bitmap2(wbxsecs,wbysecs);
|
|
3593 |
BitmapData bitmapdata2;
|
|
3594 |
bitmap2.LockBits(&Rect(0,0,wbxsecs,wbysecs),ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata2);
|
|
3595 |
UINT * pixels2=(UINT *)bitmapdata2.Scan0;
|
|
3596 |
int stride2=bitmapdata2.Stride;
|
|
3597 |
for (int i=0;i<wbysecs;i++)
|
|
3598 |
{
|
|
3599 |
for (int j=0;j<wbxsecs;j++)
|
|
3600 |
{
|
|
3601 |
COLOR c2;
|
|
3602 |
c2.R=wbsecR[i][j];
|
|
3603 |
c2.G=wbsecG[i][j];
|
|
3604 |
c2.B=wbsecB[i][j];
|
|
3605 |
pixels2[i*stride2/4+j]=c2.argb;
|
|
3606 |
}
|
|
3607 |
}
|
|
3608 |
bitmap2.UnlockBits(&bitmapdata2);
|
|
3609 |
SaveGdiPImageAsFile(&bitmap2,_T("D:\\1\\aa.bmp"));
|
|
3610 |
*/
|
|
3611 |
BrightnessCorr=1.0f;
|
|
3612 |
for (i=0;i<wbysecs;i++)
|
|
3613 |
{
|
|
3614 |
for (j=0;j<wbxsecs;j++)
|
|
3615 |
{
|
|
3616 |
float wbR=wbsecR[i][j];
|
|
3617 |
float wbG=wbsecG[i][j];
|
|
3618 |
float wbB=wbsecB[i][j];
|
|
3619 |
float wbG2=wbsecG2[i][j];
|
|
3620 |
if (wbR<32) {wbR=32;}
|
|
3621 |
if (wbG<32) {wbG=32;}
|
|
3622 |
if (wbB<32) {wbB=32;}
|
|
3623 |
if (wbG2<32) {wbG2=32;}
|
|
3624 |
float wbRcorr,wbGcorr,wbBcorr,wbG2corr;
|
|
3625 |
|
|
3626 |
if (TargetLight==0)
|
|
3627 |
{
|
|
3628 |
wbRcorr=int(128.0f*wbaveV*BrightnessCorr/wbR);
|
|
3629 |
wbGcorr=int(128.0f*wbaveV*BrightnessCorr/wbG);
|
|
3630 |
wbBcorr=int(128.0f*wbaveV*BrightnessCorr/wbB);
|
|
3631 |
wbG2corr=int(128.0f*wbaveV*BrightnessCorr/wbG2);
|
|
3632 |
}
|
|
3633 |
else if (TargetLightR*TargetLightG*TargetLightB==0)
|
|
3634 |
{
|
|
3635 |
wbRcorr=int(128.0f*TargetLight*BrightnessCorr/wbR);
|
|
3636 |
wbGcorr=int(128.0f*TargetLight*BrightnessCorr/wbG);
|
|
3637 |
wbBcorr=int(128.0f*TargetLight*BrightnessCorr/wbB);
|
|
3638 |
wbG2corr=int(128.0f*TargetLight*BrightnessCorr/wbG2);
|
|
3639 |
}else
|
|
3640 |
{
|
|
3641 |
wbRcorr=int(128.0f*TargetLightR*BrightnessCorr/wbR);
|
|
3642 |
wbGcorr=int(128.0f*TargetLightG*BrightnessCorr/wbG);
|
|
3643 |
wbBcorr=int(128.0f*TargetLightB*BrightnessCorr/wbB);
|
|
3644 |
wbG2corr=int(128.0f*TargetLightG*BrightnessCorr/wbG2);
|
|
3645 |
}
|
|
3646 |
wbsecRcorr[i][j]=wbRcorr;
|
|
3647 |
wbsecGcorr[i][j]=wbGcorr;
|
|
3648 |
wbsecBcorr[i][j]=wbBcorr;
|
|
3649 |
wbsecG2corr[i][j]=wbG2corr;
|
|
3650 |
}
|
|
3651 |
}
|
|
3652 |
/*
|
|
3653 |
Bitmap bitmap3(wbxsecs,wbysecs);
|
|
3654 |
BitmapData bitmapdata3;
|
|
3655 |
bitmap3.LockBits(&Rect(0,0,wbxsecs,wbysecs),ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata3);
|
|
3656 |
UINT * pixels3=(UINT *)bitmapdata3.Scan0;
|
|
3657 |
int stride3=bitmapdata3.Stride;
|
|
3658 |
for (int i=0;i<wbysecs;i++)
|
|
3659 |
{
|
|
3660 |
for (int j=0;j<wbxsecs;j++)
|
|
3661 |
{
|
|
3662 |
COLOR c2;
|
|
3663 |
c2.R=wbsecRcorr[i][j];
|
|
3664 |
c2.G=wbsecGcorr[i][j];
|
|
3665 |
c2.B=wbsecBcorr[i][j];
|
|
3666 |
pixels3[i*stride3/4+j]=c2.argb;
|
|
3667 |
}
|
|
3668 |
}
|
|
3669 |
bitmap3.UnlockBits(&bitmapdata3);
|
|
3670 |
SaveGdiPImageAsFile(&bitmap3,_T("D:\\1\\aa3.bmp"));
|
|
3671 |
*/
|
|
3672 |
// wbaveV=128.0f;
|
|
3673 |
/*
|
|
3674 |
for (i=0;i<ysecs;i++)
|
|
3675 |
{ yoff=i*ystep*w;
|
|
3676 |
for (j=0;j<xsecs;j++)
|
|
3677 |
{
|
|
3678 |
xoff=j*xstep;
|
|
3679 |
secV=0;
|
|
3680 |
secR=0;secG=0;secB=0;
|
|
3681 |
for(k=0;k<ystep;k++)
|
|
3682 |
{
|
|
3683 |
m=yoff+k*w;
|
|
3684 |
for (l=0;l<xstep;l++)
|
|
3685 |
{
|
|
3686 |
secR+=c1.R ;
|
|
3687 |
secG+=c1.G;
|
|
3688 |
secB+=c1.B;
|
|
3689 |
}
|
|
3690 |
}
|
|
3691 |
aveR=(float)secR/(xstep*ystep);
|
|
3692 |
aveG=(float)secG/(xstep*ystep);
|
|
3693 |
aveB=(float)secB/(xstep*ystep);
|
|
3694 |
|
|
3695 |
aveV=secV/(xstep*ystep);
|
|
3696 |
bright[i][j]=aveV;
|
|
3697 |
wbR[i][j]=aveR;
|
|
3698 |
wbG[i][j]=aveG;
|
|
3699 |
wbB[i][j]=aveB;
|
|
3700 |
totalaveR+=aveR;
|
|
3701 |
totalaveG+=aveG;
|
|
3702 |
totalaveB+=aveB;
|
|
3703 |
}
|
|
3704 |
}
|
|
3705 |
//*/
|
|
3706 |
|
|
3707 |
// double tick1=GetTickCountmS();
|
|
3708 |
|
|
3709 |
CString s1;
|
|
3710 |
// s1.Format(_T("创建白平衡数组,w,h %d %d 用时 %.2fmS\r\n"),w,h,tick1-tick0);
|
|
3711 |
// SysLog(s1);
|
|
3712 |
wbcorrloaded=1;
|
|
3713 |
autowbcorronopen=1;
|
|
3714 |
|
|
3715 |
// ((CButton *)GetDlgItem(IDC_CHECK_WBCORR))->SetCheck(true);
|
|
3716 |
|
|
3717 |
return 1;
|
|
3718 |
}
|
|
3719 |
|
|
3720 |
int SecWhiteBalance::WBCorrect(Gdiplus::Bitmap * bitmap1,Gdiplus::Bitmap * bitmap2,float fRateV, float fRateR, float fRateG, float fRateB)
|
|
3721 |
{
|
|
3722 |
return WBCorrectVC(bitmap1,bitmap2, fRateR, fRateG, fRateB);
|
|
3723 |
}
|
|
3724 |
//
|
|
3725 |
// int SecWhiteBalance::WBCorrect1(Gdiplus::Bitmap * bitmap1)
|
|
3726 |
// {
|
|
3727 |
// if (this->wbcorrloaded==0) {return 0;}
|
|
3728 |
// double tick0=GetTickCountmS();
|
|
3729 |
// int i,j,k;
|
|
3730 |
// if (bitmap1==NULL)
|
|
3731 |
// {return 0;}
|
|
3732 |
// int w,h;
|
|
3733 |
// w=bitmap1->GetWidth();
|
|
3734 |
// h=bitmap1->GetHeight();
|
|
3735 |
// if (0==w||0==h)
|
|
3736 |
// {return 0;}
|
|
3737 |
// Gdiplus::BitmapData bitmapdata0;
|
|
3738 |
// UINT * pixels;
|
|
3739 |
// Gdiplus::Rect rect0(0,0,w,h);
|
|
3740 |
// // UINT * pixels2;
|
|
3741 |
// COLOR * c2;
|
|
3742 |
// Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead|Gdiplus::ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata0);
|
|
3743 |
// if (GdipStatus!=Gdiplus::Ok)
|
|
3744 |
// {
|
|
3745 |
// CString Errs1;
|
|
3746 |
// Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
|
3747 |
// // SysLog(Errs1);
|
|
3748 |
// return 0;
|
|
3749 |
// }
|
|
3750 |
// pixels=(UINT *)bitmapdata0.Scan0 ;
|
|
3751 |
// int s=bitmapdata0.Stride/4;
|
|
3752 |
// /*
|
|
3753 |
// threadinfo1[0].pParam1=this;
|
|
3754 |
// threadinfo1[0].pParam2=0;
|
|
3755 |
// threadinfo1[0].starty=0;
|
|
3756 |
// threadinfo1[0].endy=wbysecs/2;
|
|
3757 |
// threadinfo1[0].pixels=pixels;
|
|
3758 |
// threadinfo1[0].h=h;
|
|
3759 |
// threadinfo1[0].w=w;
|
|
3760 |
// threadinfo1[0].torun=1;
|
|
3761 |
// threadinfo1[0].stride=bitmapdata0.Stride;
|
|
3762 |
// threadinfo1[0].finish=0;
|
|
3763 |
//
|
|
3764 |
// threadinfo1[1].pParam1=this;
|
|
3765 |
// threadinfo1[1].pParam2=(LPVOID)1;
|
|
3766 |
// threadinfo1[1].starty=wbysecs/2;
|
|
3767 |
// threadinfo1[1].endy=wbysecs;
|
|
3768 |
// threadinfo1[1].pixels=pixels;
|
|
3769 |
// threadinfo1[1].h=h;
|
|
3770 |
// threadinfo1[1].w=w;
|
|
3771 |
// threadinfo1[1].torun=1;
|
|
3772 |
// threadinfo1[1].stride=bitmapdata0.Stride;
|
|
3773 |
// threadinfo1[1].finish=0;
|
|
3774 |
// */
|
|
3775 |
// // CWinThread * thread1;
|
|
3776 |
// // CWinThread * thread2;
|
|
3777 |
// /*
|
|
3778 |
// thread1=AfxBeginThread(WBcorrThreadJumper,&(threadinfo1[0]),0,0,CREATE_SUSPENDED,0);
|
|
3779 |
// thread2=AfxBeginThread(WBcorrThreadJumper,&(threadinfo1[1]),0,0,CREATE_SUSPENDED,0);
|
|
3780 |
// // thread1->m_bAutoDelete=true;
|
|
3781 |
// // thread2->m_bAutoDelete=true;
|
|
3782 |
// // ::SetThreadAffinityMask(thread1->m_hThread,0x00000001);
|
|
3783 |
// // ::SetThreadAffinityMask(thread2->m_hThread,0x00000002);
|
|
3784 |
// thread1->ResumeThread();
|
|
3785 |
// thread2->ResumeThread();
|
|
3786 |
// for (i=0;i<10000;i++)
|
|
3787 |
// {
|
|
3788 |
// if (threadinfo1[0].finish==0||threadinfo1[1].finish==0)
|
|
3789 |
// {
|
|
3790 |
// Sleep(10);
|
|
3791 |
// }
|
|
3792 |
// else
|
|
3793 |
// {
|
|
3794 |
// break;
|
|
3795 |
// }
|
|
3796 |
// }
|
|
3797 |
// //*/
|
|
3798 |
// // int xsec,ysec;
|
|
3799 |
// // int m,n;
|
|
3800 |
// // COLOR c1;
|
|
3801 |
// // int secV;
|
|
3802 |
// // int aveV;
|
|
3803 |
//
|
|
3804 |
// int yoff,ystep,xoff,xstep;
|
|
3805 |
// int offset;
|
|
3806 |
// float wbR,wbG,wbB;
|
|
3807 |
// // short int R,G,B;
|
|
3808 |
// short int wbRcorr,wbGcorr,wbBcorr;
|
|
3809 |
// // if (0)
|
|
3810 |
// for (i=0;i<wbysecs;i++)
|
|
3811 |
// { yoff=i*h/wbysecs;
|
|
3812 |
// ystep=(i+1)*h/wbysecs-yoff;
|
|
3813 |
// for (j=0;j<wbxsecs;j++)
|
|
3814 |
// {
|
|
3815 |
// xoff=j*w/wbxsecs;
|
|
3816 |
// xstep=(j+1)*w/wbxsecs-xoff;
|
|
3817 |
// wbR=wbsecR[i][j];
|
|
3818 |
// wbG=wbsecG[i][j];
|
|
3819 |
// wbB=wbsecB[i][j];
|
|
3820 |
// if (wbR<32) {wbR=32;}
|
|
3821 |
// if (wbG<32) {wbG=32;}
|
|
3822 |
// if (wbB<32) {wbB=32;}
|
|
3823 |
// if (TargetLight==0)
|
|
3824 |
// {
|
|
3825 |
// wbRcorr=int(128.0f*wbaveV*BrightnessCorr/wbR);
|
|
3826 |
// wbGcorr=int(128.0f*wbaveV*BrightnessCorr/wbG);
|
|
3827 |
// wbBcorr=int(128.0f*wbaveV*BrightnessCorr/wbB);
|
|
3828 |
// }
|
|
3829 |
// else if (TargetLightR*TargetLightG*TargetLightB==0)
|
|
3830 |
// {
|
|
3831 |
// wbRcorr=int(128.0f*TargetLight*BrightnessCorr/wbR);
|
|
3832 |
// wbGcorr=int(128.0f*TargetLight*BrightnessCorr/wbG);
|
|
3833 |
// wbBcorr=int(128.0f*TargetLight*BrightnessCorr/wbB);
|
|
3834 |
// }else
|
|
3835 |
// {
|
|
3836 |
// wbRcorr=int(128.0f*TargetLightR*BrightnessCorr/wbR);
|
|
3837 |
// wbGcorr=int(128.0f*TargetLightG*BrightnessCorr/wbG);
|
|
3838 |
// wbBcorr=int(128.0f*TargetLightB*BrightnessCorr/wbB);
|
|
3839 |
// }
|
|
3840 |
// //continue;
|
|
3841 |
// // 设置相乘系数
|
|
3842 |
// /*
|
|
3843 |
// __int64 corr = 0;
|
|
3844 |
// corr = wbRcorr;
|
|
3845 |
// corr = corr << 16;
|
|
3846 |
// corr |= wbGcorr;
|
|
3847 |
// corr = corr << 16;
|
|
3848 |
// corr |= wbBcorr;
|
|
3849 |
// _mm_empty(); // 清空MMX寄存器。
|
|
3850 |
//
|
|
3851 |
// __m64 nNull = _m_from_int(0); // null
|
|
3852 |
// __m64 tmp = _m_from_int(0); // 临时工作临时变量初始化
|
|
3853 |
//
|
|
3854 |
// __m64 nCoeff = Get_m64(corr);
|
|
3855 |
// __m128 corr128;
|
|
3856 |
// corr128.m128_u16[0]=wbBcorr;
|
|
3857 |
// corr128.m128_u16[1]=wbGcorr;
|
|
3858 |
// corr128.m128_u16[2]=wbRcorr;
|
|
3859 |
// corr128.m128_u16[3]=0;
|
|
3860 |
// corr128.m128_u16[4]=wbBcorr;
|
|
3861 |
// corr128.m128_u16[5]=wbGcorr;
|
|
3862 |
// corr128.m128_u16[6]=wbRcorr;
|
|
3863 |
// corr128.m128_u16[7]=0;
|
|
3864 |
// __m128 nCorr128=corr128;
|
|
3865 |
// */
|
|
3866 |
// // __m128 nNull128;
|
|
3867 |
// // __m128 temp2;
|
|
3868 |
//
|
|
3869 |
//
|
|
3870 |
// // DWORD* pIn = (DWORD*) pSource; // 输入双字数组
|
|
3871 |
// // DWORD* pOut = (DWORD*) pDest; // 输出双字数组
|
|
3872 |
//
|
|
3873 |
//
|
|
3874 |
// // _mm_set_ps(1.0f,2.0f,3.0f,4.0f);
|
|
3875 |
//
|
|
3876 |
// for (k=0;k<ystep;k++)
|
|
3877 |
// {
|
|
3878 |
// offset=(yoff+k)*s+xoff;
|
|
3879 |
//
|
|
3880 |
// //continue;
|
|
3881 |
// c2=(COLOR *)(pixels+offset);
|
|
3882 |
// //for (l=0;l<xstep;l++)
|
|
3883 |
// {// pixels2=pixels+offset+l;
|
|
3884 |
// //continue;
|
|
3885 |
// /* ==============//C语言代码 =========== 109mS
|
|
3886 |
// R=c2->R*wbRcorr>>7;
|
|
3887 |
// if (R>255) {c1.R=255;}
|
|
3888 |
// else {c2->R=R;}
|
|
3889 |
// G=c2->G*wbGcorr>>7;
|
|
3890 |
// c2->G=min(255,G);
|
|
3891 |
// B=c2->B*wbBcorr>>7;
|
|
3892 |
// c2->B =min(255,B);
|
|
3893 |
// c2++;
|
|
3894 |
// //*/ //========================================
|
|
3895 |
//
|
|
3896 |
// /* //======================MMX 代码==================================== 120mS
|
|
3897 |
// if (usemmx)
|
|
3898 |
// {
|
|
3899 |
// tmp = _m_from_int(c2->argb); // tmp = *pIn (在tmp的低32位写入数据)
|
|
3900 |
//
|
|
3901 |
// tmp = _mm_unpacklo_pi8(tmp, nNull ); //将tmp中低位的4个字节转化为字
|
|
3902 |
// //字的高位用nNull中对应位上的位值填充。
|
|
3903 |
//
|
|
3904 |
// tmp = _mm_mullo_pi16 (tmp , nCoeff); //将tmp中的每一个字相乘,将相乘结果的高位送到nCoeff,在tmp中只保留每个结果的低位。
|
|
3905 |
//
|
|
3906 |
// tmp = _mm_srli_pi16 (tmp , 7); // 将tmp中的每一个字右移7位,相当于除以128
|
|
3907 |
//
|
|
3908 |
// tmp = _mm_packs_pu16 (tmp, nNull); // 使用饱和模式将tmp中的结果做如下处理:
|
|
3909 |
// //将tmp中的4个字转化为4个字节,并将这4个字节写到tmp中的低32位中
|
|
3910 |
// // 同时,将nNull中的4个字转化为4个字节,并将这4个字节写到tmp的高32位中。
|
|
3911 |
//
|
|
3912 |
// c2->argb = _m_to_int(tmp)|0xff000000; // *pOut = tmp (将tmp低32位的数据放入pOut数组中)
|
|
3913 |
// c2++;
|
|
3914 |
// }
|
|
3915 |
// //*/ //=======================================================
|
|
3916 |
// ////======================= SSE INTRIC 代码 ========================
|
|
3917 |
// //__m128 a1=_mm_setzero_ps();
|
|
3918 |
// //a1=_mm_load
|
|
3919 |
// // __m128 a;
|
|
3920 |
// // __m128i b;
|
|
3921 |
// // __m128d c;
|
|
3922 |
// // _mm_packuswb()
|
|
3923 |
// ///* //==================== SSE 汇编优化 ========================== 30mS
|
|
3924 |
// int xstep_2=xstep/2;
|
|
3925 |
// /*
|
|
3926 |
// _asm
|
|
3927 |
// {
|
|
3928 |
// //tmp=_m_from_int(c2->argb);
|
|
3929 |
// //start:
|
|
3930 |
// movq xmm0,mmword ptr[nNull];
|
|
3931 |
// movdqa xmm4,nCorr128;
|
|
3932 |
// mov eax,c2;
|
|
3933 |
// sub eax,4;
|
|
3934 |
// mov ecx,xstep;
|
|
3935 |
// loop1:
|
|
3936 |
// //mov edx,dword ptr [eax+ecx*4]
|
|
3937 |
// movd xmm1,dword ptr [eax+ecx*4]; //edx;
|
|
3938 |
// // movd mm1,dword ptr [eax+ecx*4];
|
|
3939 |
// // movq mmword ptr[tmp],mm0;
|
|
3940 |
// //tmp=_mm_unpacklo_pi8(tmp,nNull);
|
|
3941 |
// //movq xmm0,mmword ptr [nNull];
|
|
3942 |
// // movdqa xmm2,xmm0
|
|
3943 |
// movaps xmm2,xmm0
|
|
3944 |
// // movq mm0,mmword ptr [tmp];
|
|
3945 |
// movaps xmm3,xmm4
|
|
3946 |
//
|
|
3947 |
// punpcklbw xmm1,xmm2;
|
|
3948 |
// // movq mmword ptr [tmp],mm1;
|
|
3949 |
// // tmp=_mm_mull0_pi16(tmp,nCoeff);
|
|
3950 |
// //movdq xmm2,xmmword ptr [nCoeff]
|
|
3951 |
// // movdqa xmm2,nCorr128;
|
|
3952 |
//
|
|
3953 |
// // movq mm1,mmword ptr[tmp]
|
|
3954 |
// pmullw xmm1,xmm3; 注释
|
|
3955 |
// // movq mmword ptr[tmp],mm1
|
|
3956 |
// // tmp = _mm_srli_pi16(tmp,7)
|
|
3957 |
// // movq mm0,mmword ptr[tmp]
|
|
3958 |
// psrlw xmm1,7;
|
|
3959 |
// // movq mmwordptr[tmp],mm1;
|
|
3960 |
// //tmp=_mm_packs_pu16(tmp,nNull);
|
|
3961 |
// // movq mm0,mmword ptr [nNull]
|
|
3962 |
// // movq mm1,mmword ptr [tmp]
|
|
3963 |
// packuswb xmm1,xmm2;
|
|
3964 |
// // movq mmword ptr [tmp],mm1;
|
|
3965 |
// //c2->argb=_m_to_int(tmp)|0xff000000;
|
|
3966 |
// // movq mm1,mmword ptr[tmp]
|
|
3967 |
// movd dword ptr [eax+ecx*4],xmm1;
|
|
3968 |
// //or edx,0ff000000h;
|
|
3969 |
// //mov dword ptr[eax+ecx*4],edx;
|
|
3970 |
// //mulps xmm3,xmm4;
|
|
3971 |
//
|
|
3972 |
// loop loop1
|
|
3973 |
//
|
|
3974 |
// //dec ebx;
|
|
3975 |
// //jne loop1;
|
|
3976 |
// }
|
|
3977 |
// */
|
|
3978 |
// //*///===============================================================
|
|
3979 |
//
|
|
3980 |
// }
|
|
3981 |
// }
|
|
3982 |
// // _mm_empty();
|
|
3983 |
// }
|
|
3984 |
// }
|
|
3985 |
//
|
|
3986 |
//
|
|
3987 |
// bitmap1->UnlockBits(&bitmapdata0);
|
|
3988 |
// double tick1=GetTickCountmS();
|
|
3989 |
// CString s1;
|
|
3990 |
// // s1.Format(_T("白平衡修正完成 用时 %.2fmS\r\n"),tick1-tick0);
|
|
3991 |
// // SysLog1(s1);
|
|
3992 |
// return 1;
|
|
3993 |
// }
|
|
3994 |
int SecWhiteBalance::WBCorrectVC(Gdiplus::Bitmap * bitmap1,Gdiplus::Bitmap * bitmap2,float fRateV, float fRateR, float fRateG, float fRateB)
|
|
3995 |
{
|
|
3996 |
if (bitmap2==NULL||bitmap1==bitmap2)
|
|
3997 |
{
|
|
3998 |
return WBCorrect1VC(bitmap1,fRateV, fRateR, fRateG, fRateB);
|
|
3999 |
}
|
|
4000 |
else
|
|
4001 |
{
|
|
4002 |
return WBCorrect2VC(bitmap1,bitmap2,fRateV, fRateR, fRateG, fRateB);
|
|
4003 |
}
|
|
4004 |
return 0;
|
|
4005 |
}
|
|
4006 |
|
|
4007 |
int SecWhiteBalance::WBCorrect1VC(Gdiplus::Bitmap * bitmap1,float fRateV, float fRateR, float fRateG, float fRateB)
|
|
4008 |
{
|
|
4009 |
if (this->wbcorrloaded==0) {return 0;}
|
|
4010 |
double tick0=GetTickCountmS();
|
|
4011 |
int i,j,k;
|
|
4012 |
if (bitmap1==NULL)
|
|
4013 |
{return 0;}
|
|
4014 |
int w,h;
|
|
4015 |
w=bitmap1->GetWidth();
|
|
4016 |
h=bitmap1->GetHeight();
|
|
4017 |
if (0==w||0==h)
|
|
4018 |
{return 0;}
|
|
4019 |
Gdiplus::BitmapData bitmapdata0;
|
|
4020 |
UINT * pixels;
|
|
4021 |
Gdiplus::Rect rect0(0,0,w,h);
|
|
4022 |
// UINT * pixels2;
|
|
4023 |
COLOR * c2;
|
|
4024 |
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead|Gdiplus::ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata0);
|
|
4025 |
if (GdipStatus!=Gdiplus::Ok)
|
|
4026 |
{
|
|
4027 |
CString Errs1;
|
|
4028 |
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
|
4029 |
// SysLog(Errs1);
|
|
4030 |
return 0;
|
|
4031 |
}
|
|
4032 |
pixels=(UINT *)bitmapdata0.Scan0 ;
|
|
4033 |
int s=bitmapdata0.Stride/4;
|
|
4034 |
int yoff,ystep,xoff,xstep;
|
|
4035 |
int offset;
|
|
4036 |
float wbR,wbG,wbB;
|
|
4037 |
short int R,G,B;
|
|
4038 |
short int wbRcorr,wbGcorr,wbBcorr;
|
|
4039 |
// if (0)
|
|
4040 |
for (i=0;i<wbysecs;i++)
|
|
4041 |
|
|
4042 |
{ yoff=i*h/wbysecs;
|
|
4043 |
ystep=(i+1)*h/wbysecs-yoff;
|
|
4044 |
for (j=0;j<wbxsecs;j++)
|
|
4045 |
{
|
|
4046 |
xoff=j*w/wbxsecs;
|
|
4047 |
xstep=(j+1)*w/wbxsecs-xoff;
|
|
4048 |
wbR=wbsecR[i][j];
|
|
4049 |
wbG=wbsecG[i][j];
|
|
4050 |
wbB=wbsecB[i][j];
|
|
4051 |
if (wbR<32) {wbR=32;}
|
|
4052 |
if (wbG<32) {wbG=32;}
|
|
4053 |
if (wbB<32) {wbB=32;}
|
|
4054 |
if (TargetLight==0)
|
|
4055 |
{
|
|
4056 |
wbRcorr=int(128.0f*wbaveV*fRateV/wbR);
|
|
4057 |
wbGcorr=int(128.0f*wbaveV*fRateV/wbG);
|
|
4058 |
wbBcorr=int(128.0f*wbaveV*fRateV/wbB);
|
|
4059 |
}
|
|
4060 |
else if (TargetLightR*TargetLightG*TargetLightB==0)
|
|
4061 |
{
|
|
4062 |
wbRcorr=int(128.0f*TargetLight*fRateV/wbR);
|
|
4063 |
wbGcorr=int(128.0f*TargetLight*fRateV/wbG);
|
|
4064 |
wbBcorr=int(128.0f*TargetLight*fRateV/wbB);
|
|
4065 |
}else
|
|
4066 |
{
|
|
4067 |
wbRcorr=int(128.0f*TargetLightR*fRateR/wbR);
|
|
4068 |
wbGcorr=int(128.0f*TargetLightG*fRateG/wbG);
|
|
4069 |
wbBcorr=int(128.0f*TargetLightB*fRateB/wbB);
|
|
4070 |
}
|
|
4071 |
//wbRcorr=0;
|
|
4072 |
//wbGcorr=0;
|
|
4073 |
//wbBcorr=0;
|
|
4074 |
for (k=0;k<ystep;k++)
|
|
4075 |
{
|
|
4076 |
offset=(yoff+k)*s+xoff;
|
|
4077 |
|
|
4078 |
//continue;
|
|
4079 |
c2=(COLOR *)(pixels+offset);
|
|
4080 |
for (int l=0;l<xstep;l++)
|
|
4081 |
{// pixels2=pixels+offset+l;
|
|
4082 |
//continue;
|
|
4083 |
R=c2->R*wbRcorr>>7;
|
|
4084 |
c2->R=min(255,R);
|
|
4085 |
G=c2->G*wbGcorr>>7;
|
|
4086 |
c2->G=min(255,G);
|
|
4087 |
B=c2->B*wbBcorr>>7;
|
|
4088 |
c2->B =min(255,B);
|
|
4089 |
// c2->R=0;
|
|
4090 |
c2++;
|
|
4091 |
}
|
|
4092 |
}
|
|
4093 |
}
|
|
4094 |
}
|
|
4095 |
bitmap1->UnlockBits(&bitmapdata0);
|
|
4096 |
double tick1=GetTickCountmS();
|
|
4097 |
return 1;
|
|
4098 |
}
|
|
4099 |
int SecWhiteBalance::WBCorrect2VC(Gdiplus::Bitmap * bitmap1,Gdiplus::Bitmap * bitmap2,float fRateV, float fRateR, float fRateG, float fRateB)
|
|
4100 |
{
|
|
4101 |
return 1;
|
|
4102 |
}
|
|
4103 |
|
|
4104 |
int SecWhiteBalance::WBBayerCorrect(MyImage * Image1,MyImage * Image2,float fRateV, float fRateR, float fRateG, float fRateB)
|
|
4105 |
{
|
|
4106 |
return WBBayerCorrectVC(Image1, Image2, fRateV, fRateR, fRateG, fRateB);
|
|
4107 |
}
|
|
4108 |
int SecWhiteBalance::WBBayerCorrectVC(MyImage * Image1,MyImage * Image2,float fRateV, float fRateR, float fRateG, float fRateB)
|
|
4109 |
{
|
|
4110 |
if (Image2==NULL||Image1==Image2)
|
|
4111 |
{
|
|
4112 |
return WBBayerCorrect1VC(Image1->buffer,Image1->GetWidth(),Image1->GetHeight(),Image1->Stride, fRateV, fRateR, fRateG, fRateB);
|
|
4113 |
}
|
|
4114 |
else
|
|
4115 |
{
|
|
4116 |
return WBBayerCorrect2VC(Image1,Image2,fRateV, fRateR, fRateG, fRateB);
|
|
4117 |
}
|
|
4118 |
return 0;
|
|
4119 |
}
|
|
4120 |
int SecWhiteBalance::WBBayerCorrect1VC(void * buf1,int w,int h,int stride,float fRateV, float fRateR, float fRateG, float fRateB)
|
|
4121 |
{
|
|
4122 |
if (this->wbcorrloaded==0) {return 0;}
|
|
4123 |
double tick0=GetTickCountmS();
|
|
4124 |
int i,j,k;
|
|
4125 |
if (buf1==NULL) {return 0;}
|
|
4126 |
// int w,h;
|
|
4127 |
// w=Image1->GetWidth();
|
|
4128 |
// h=Image1->GetHeight();
|
|
4129 |
if (0==w||0==h)
|
|
4130 |
{return 0;}
|
|
4131 |
// Gdiplus::BitmapData bitmapdata0;
|
|
4132 |
unsigned char * pixels;
|
|
4133 |
pixels=(unsigned char *)buf1 ;
|
|
4134 |
int yoff,ystep,xoff,xstep;
|
|
4135 |
int offset;
|
|
4136 |
// float wbR,wbG,wbB,wbG2;
|
|
4137 |
short int R,G,B,G2;
|
|
4138 |
short int wbRcorr,wbGcorr,wbBcorr,wbG2corr;
|
|
4139 |
|
|
4140 |
for (i=0;i<wbysecs;i++)
|
|
4141 |
{ yoff=i*(h/2)/wbysecs*2;
|
|
4142 |
ystep=(i+1)*(h/2)/wbysecs*2-yoff;
|
|
4143 |
for (j=0;j<wbxsecs;j++)
|
|
4144 |
{
|
|
4145 |
xoff=j*(w/2)/wbxsecs*2;
|
|
4146 |
xstep=(j+1)*(w/2)/wbxsecs*2-xoff;
|
|
4147 |
wbRcorr=wbsecRcorr[i][j]*fRateR;
|
|
4148 |
wbGcorr=wbsecGcorr[i][j]*fRateG;
|
|
4149 |
wbBcorr=wbsecBcorr[i][j]*fRateB;
|
|
4150 |
wbG2corr=wbsecG2corr[i][j]*fRateG;
|
|
4151 |
for (k=0;k<ystep;k+=2)
|
|
4152 |
{
|
|
4153 |
offset=(yoff+k)*stride+xoff;
|
|
4154 |
unsigned char * c2;
|
|
4155 |
//continue;
|
|
4156 |
c2=(unsigned char *)(pixels+offset);
|
|
4157 |
for (int l=0;l<xstep;l+=2)
|
|
4158 |
{// pixels2=pixels+offset+l;
|
|
4159 |
//continue;
|
|
4160 |
|
|
4161 |
G=(pixels[offset+l]*wbGcorr+64)/128;
|
|
4162 |
pixels[offset+l]=min(255,G);;
|
|
4163 |
R=(pixels[offset+l+1]*wbRcorr+64)/128;
|
|
4164 |
pixels[offset+l+1]=min(255,R);
|
|
4165 |
B=(pixels[offset+stride+l]*wbBcorr+64)/128;
|
|
4166 |
pixels[offset+stride+l]=min(255,B);
|
|
4167 |
G2=(pixels[offset+stride+l+1]*wbG2corr+64)/128;
|
|
4168 |
pixels[offset+stride+l+1]=min(255,G2);
|
|
4169 |
}
|
|
4170 |
}
|
|
4171 |
}
|
|
4172 |
}
|
|
4173 |
double tick1=GetTickCountmS();
|
|
4174 |
return 0;
|
|
4175 |
}
|
|
4176 |
int SecWhiteBalance::WBBayerCorrect2VC(MyImage * Image1,MyImage * Image2,float fRateV, float fRateR, float fRateG, float fRateB)
|
|
4177 |
{
|
|
4178 |
if (this->wbcorrloaded==0) {return -1;}
|
|
4179 |
double tick0=GetTickCountmS();
|
|
4180 |
int i,j,k;
|
|
4181 |
if (Image1==NULL) {return -1;}
|
|
4182 |
if (!Image1->IsValid) {return -1;}
|
|
4183 |
int w,h;
|
|
4184 |
w=Image1->GetWidth();
|
|
4185 |
h=Image1->GetHeight();
|
|
4186 |
if (0==w||0==h)
|
|
4187 |
{return 0;}
|
|
4188 |
int w2,h2;
|
|
4189 |
if (Image2==NULL) {return -1;}
|
|
4190 |
if (!Image2->IsValid){Image2->AllocBuf(w,h,w,MyImage::MyPixelType_BayerGR8);}
|
|
4191 |
w2=Image2->GetWidth();h2=Image2->GetHeight();
|
|
4192 |
if (w!=w2||h!=h2) {Image2->AllocBuf(w,h,w,MyImage::MyPixelType_BayerGR8);}
|
|
4193 |
unsigned char * pixels;
|
|
4194 |
pixels=(unsigned char *)Image1->GetBuffer();
|
|
4195 |
unsigned char * pixels2;
|
|
4196 |
pixels2=(unsigned char *)Image2->GetBuffer();
|
|
4197 |
int stride=Image1->GetStride();
|
|
4198 |
int yoff,ystep,xoff,xstep;
|
|
4199 |
int offset;
|
|
4200 |
// float wbR,wbG,wbB,wbG2;
|
|
4201 |
short int R,G,B,G2;
|
|
4202 |
short int wbRcorr,wbGcorr,wbBcorr,wbG2corr;
|
|
4203 |
|
|
4204 |
for (i=0;i<wbysecs;i++)
|
|
4205 |
{ yoff=i*(h/2)/wbysecs*2;
|
|
4206 |
ystep=(i+1)*(h/2)/wbysecs*2-yoff;
|
|
4207 |
for (j=0;j<wbxsecs;j++)
|
|
4208 |
{
|
|
4209 |
xoff=j*(w/2)/wbxsecs*2;
|
|
4210 |
xstep=(j+1)*(w/2)/wbxsecs*2-xoff;
|
|
4211 |
|
|
4212 |
wbRcorr=wbsecRcorr[i][j]*fRateR;
|
|
4213 |
wbGcorr=wbsecGcorr[i][j]*fRateG;
|
|
4214 |
wbBcorr=wbsecBcorr[i][j]*fRateB;
|
|
4215 |
wbG2corr=wbsecG2corr[i][j]*fRateG;
|
|
4216 |
for (k=0;k<ystep;k+=2)
|
|
4217 |
{
|
|
4218 |
offset=(yoff+k)*stride+xoff;
|
|
4219 |
unsigned char * c2;
|
|
4220 |
//continue;
|
|
4221 |
c2=(unsigned char *)(pixels+offset);
|
|
4222 |
for (int l=0;l<xstep;l+=2)
|
|
4223 |
{// pixels2=pixels+offset+l;
|
|
4224 |
//continue;
|
|
4225 |
G=(pixels[offset+l]*wbGcorr+64)/128;
|
|
4226 |
pixels2[offset+l]=min(255,G);;
|
|
4227 |
R=(pixels[offset+l+1]*wbRcorr+64)/128;
|
|
4228 |
pixels2[offset+l+1]=min(255,R);
|
|
4229 |
B=(pixels[offset+stride+l]*wbBcorr+64)/128;
|
|
4230 |
pixels2[offset+stride+l]=min(255,B);
|
|
4231 |
G2=(pixels[offset+stride+l+1]*wbG2corr+64)/128;
|
|
4232 |
pixels2[offset+stride+l+1]=min(255,G2);
|
|
4233 |
}
|
|
4234 |
}
|
|
4235 |
}
|
|
4236 |
}
|
|
4237 |
double tick1=GetTickCountmS();
|
|
4238 |
return 0;
|
|
4239 |
return -1;
|
|
4240 |
}
|
|
4241 |
|
|
4242 |
int AveFilter(int inCount, int FilterSize, double inbuf[], double outbuf[])
|
|
4243 |
{
|
|
4244 |
return inCount;
|
|
4245 |
}
|
|
4246 |
int MidFilter(int inCount, int FilterSize, double inbuf[], double outbuf[])
|
|
4247 |
{
|
|
4248 |
return inCount;
|
|
4249 |
}
|
|
4250 |
int juanji(int incount,int corecount,double inbuf[], double outbuf[],double corebuf[])
|
|
4251 |
{
|
|
4252 |
int i,j;
|
|
4253 |
int k1=(corecount)/2;
|
|
4254 |
int k2=(corecount+1)/2;
|
|
4255 |
int l;
|
|
4256 |
double sum1;
|
|
4257 |
for (i=0;i<k1;i++) //起始边缘处理
|
|
4258 |
{
|
|
4259 |
sum1=0;
|
|
4260 |
for (j=0;j<corecount;j++)
|
|
4261 |
{
|
|
4262 |
l=i-k1+j;
|
|
4263 |
if (l<0) {l=0;}
|
|
4264 |
sum1+=inbuf[l]*corebuf[j];
|
|
4265 |
}
|
|
4266 |
outbuf[i]=sum1;
|
|
4267 |
}
|
|
4268 |
for (i=k1;i<incount-k1;i++) //正常值处理
|
|
4269 |
{
|
|
4270 |
sum1=0;
|
|
4271 |
for (j=0;j<corecount;j++)
|
|
4272 |
{
|
|
4273 |
l=i-k1+j;
|
|
4274 |
sum1+=inbuf[l]*corebuf[j];
|
|
4275 |
}
|
|
4276 |
outbuf[i]=sum1;
|
|
4277 |
// outbuf[i]=inbuf[i];
|
|
4278 |
}
|
|
4279 |
for (i=incount-k1;i<incount;i++) //结束边缘处理
|
|
4280 |
{
|
|
4281 |
sum1=0;
|
|
4282 |
for (j=0;j<corecount;j++)
|
|
4283 |
{
|
|
4284 |
l=i-k1+j;
|
|
4285 |
if (l>incount-1) {l=incount-1;}
|
|
4286 |
sum1+=inbuf[l]*corebuf[j];
|
|
4287 |
}
|
|
4288 |
outbuf[i]=sum1;
|
|
4289 |
}
|
|
4290 |
return i;
|
|
4291 |
}
|
|
4292 |
|
|
4293 |
int juanjiV(int incount,int corecount,int stride, int x, double inbuf[], double outbuf[],double corebuf[])
|
|
4294 |
{
|
|
4295 |
int i,j;
|
|
4296 |
int k1=(corecount)/2;
|
|
4297 |
int l;
|
|
4298 |
double sum1;
|
|
4299 |
for (i=0;i<incount;i++)
|
|
4300 |
{
|
|
4301 |
sum1=0;
|
|
4302 |
for (j=0;j<corecount;j++)
|
|
4303 |
{
|
|
4304 |
l=i-k1+j;
|
|
4305 |
if (l<0)
|
|
4306 |
{
|
|
4307 |
l=0;
|
|
4308 |
}
|
|
4309 |
if (l>incount-1)
|
|
4310 |
{
|
|
4311 |
l=incount-1;
|
|
4312 |
}
|
|
4313 |
sum1+=inbuf[l*stride + x]*corebuf[j];
|
|
4314 |
}
|
|
4315 |
outbuf[i*stride + x]=sum1;
|
|
4316 |
}
|
|
4317 |
|
|
4318 |
return i;
|
|
4319 |
}
|
|
4320 |
|
|
4321 |
int juanji2D(double inbuf[], int sizex, int sizey, int stride, double outbuf[], double corebuf[], int coresizex, int coresizey, int corestrie)
|
|
4322 |
{
|
|
4323 |
int halfcorex=coresizex/2;
|
|
4324 |
int halfcorey=coresizey/2;
|
|
4325 |
|
|
4326 |
//for (int i = 0; i < sizey; i++)
|
|
4327 |
//{
|
|
4328 |
// int l0 = i*stride;
|
|
4329 |
// int startcory = (i - halfcorey < 0) ? halfcorey - i : 0;
|
|
4330 |
// int endcory = (i + coresizey - 1 >= sizey) ? coresizey - (i + coresizey - sizey) : coresizey;
|
|
4331 |
// for (int j = 0; j < sizex; j++)
|
|
4332 |
// {
|
|
4333 |
// int startcorx = (j - halfcorex < 0) ? halfcorex - j : 0;;
|
|
4334 |
// int endcorx = (j + coresizex - 1 >= sizex) ? coresizex - (j + coresizex - sizex) : coresizex;
|
|
4335 |
// int l1 = l0 + j;
|
|
4336 |
// outbuf[l1] = 0;
|
|
4337 |
// for (int k = startcory; k < endcory; k++)
|
|
4338 |
// {
|
|
4339 |
// int l2 = l1 + (k - halfcorey)*stride;
|
|
4340 |
|
|
4341 |
// for (int l = startcorx; l < endcorx; l++)
|
|
4342 |
// {
|
|
4343 |
// outbuf[l1] += inbuf[l2 + (l - halfcorex)] * corebuf[k*corestrie + l];
|
|
4344 |
// }
|
|
4345 |
// }
|
|
4346 |
|
|
4347 |
// }
|
|
4348 |
//}
|
|
4349 |
|
|
4350 |
for (int i = 0; i < halfcorey; i++)
|
|
4351 |
{
|
|
4352 |
int l0 = i*stride;
|
|
4353 |
for (int j = 0; j < halfcorex; j++) outbuf[l0 + j] = 0;
|
|
4354 |
for (int j = sizex-halfcorex; j < sizex; j++) outbuf[l0 + j] = 0;
|
|
4355 |
}
|
|
4356 |
|
|
4357 |
for (int i = sizey-halfcorey; i < sizey; i++)
|
|
4358 |
{
|
|
4359 |
int l0 = i*stride;
|
|
4360 |
for (int j = 0; j < halfcorex; j++) outbuf[l0 + j] = 0;
|
|
4361 |
for (int j = sizex - halfcorex; j < sizex; j++) outbuf[l0 + j] = 0;
|
|
4362 |
}
|
|
4363 |
|
|
4364 |
for (int i=halfcorey;i<sizey-halfcorey;i++) //正常运算
|
|
4365 |
{
|
|
4366 |
int l0=i*stride;
|
|
4367 |
for (int j=halfcorex;j<sizex-halfcorex;j++)
|
|
4368 |
{
|
|
4369 |
int l1=l0+j;
|
|
4370 |
outbuf[l1]=0;
|
|
4371 |
for (int k=0;k<coresizey;k++)
|
|
4372 |
{
|
|
4373 |
int l2=l1+(k-halfcorey)*stride;
|
|
4374 |
for (int l=0;l<coresizex;l++)
|
|
4375 |
{
|
|
4376 |
outbuf[l1]+=inbuf[l2+(l-halfcorex)]*corebuf[k*corestrie+l];
|
|
4377 |
}
|
|
4378 |
}
|
|
4379 |
}
|
|
4380 |
}
|
|
4381 |
|
|
4382 |
return sizex*sizey;
|
|
4383 |
}
|
|
4384 |
// template <typename T>
|
|
4385 |
// int juanji2D3x3(T inbuf[], int sizex, int sizey, int stride, T outbuf[], T corebuf[3][3])
|
|
4386 |
// {
|
|
4387 |
//
|
|
4388 |
// for (int i=1;i<sizey-1;i++) //正常运算//内部区域
|
|
4389 |
// {
|
|
4390 |
// int l0=(i-1)*stride;
|
|
4391 |
// int l1=(i)*stride;
|
|
4392 |
// int l2=(i+1)*stride;
|
|
4393 |
// for (int j=1;j<sizex-1;j++)
|
|
4394 |
// {
|
|
4395 |
// T a1,a2,a3;
|
|
4396 |
// a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
|
|
4397 |
// a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
|
4398 |
// a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
|
4399 |
// outbuf[l1+j]=a1+a2+a3;
|
|
4400 |
// }
|
|
4401 |
// }
|
|
4402 |
// for (int i=0;i<1;i++) //处理边缘,上边缘,不包括左上角和右上角;
|
|
4403 |
// {
|
|
4404 |
// int l1=(i)*stride;
|
|
4405 |
// int l2=(i+1)*stride;
|
|
4406 |
// for (int j=1;j<sizex-1;j++)
|
|
4407 |
// {
|
|
4408 |
// outbuf[l1+j]=outbuf[l2+j];
|
|
4409 |
// }
|
|
4410 |
// }
|
|
4411 |
// for (int i=sizey-1;i<sizey;i++) //下边缘,不包括左下角和右下角
|
|
4412 |
// {
|
|
4413 |
// int l0=(i-1)*stride;
|
|
4414 |
// int l1=(i)*stride;
|
|
4415 |
//
|
|
4416 |
// for (int j=1;j<sizex-1;j++)
|
|
4417 |
// {
|
|
4418 |
// outbuf[l1+j]=outbuf[l0+j];
|
|
4419 |
// }
|
|
4420 |
// }
|
|
4421 |
// for (int i=1;i<sizey-1;i++) //左边缘,不包括左上角和左下角
|
|
4422 |
// {
|
|
4423 |
// int l=(i)*stride;
|
|
4424 |
// for (int j=0;j<1;j++)
|
|
4425 |
// {
|
|
4426 |
// outbuf[l+j]=outbuf[l+j+1];
|
|
4427 |
// }
|
|
4428 |
// }
|
|
4429 |
// for (int i=1;i<sizey-1;i++) //右边缘,不包括右上角和右下角
|
|
4430 |
// {
|
|
4431 |
// int l=(i)*stride;
|
|
4432 |
// for (int j=sizex-1;j<sizex;j++)
|
|
4433 |
// {
|
|
4434 |
// outbuf[l+j]=outbuf[l+j-1];
|
|
4435 |
// }
|
|
4436 |
// }
|
|
4437 |
// //四个角
|
|
4438 |
// for (int i=0;i<1;i++)
|
|
4439 |
// {
|
|
4440 |
// int l1=(i)*stride;
|
|
4441 |
// int l2=(i+1)*stride;
|
|
4442 |
// for (int j=0;j<1;j++)
|
|
4443 |
// {
|
|
4444 |
// T a1,a2,a3;
|
|
4445 |
// outbuf[l1+j]=(outbuf[l2+j]+outbuf[l1+j+1])/2;
|
|
4446 |
// }
|
|
4447 |
// for (int j=sizex-1;j<sizex;j++)
|
|
4448 |
// {
|
|
4449 |
// outbuf[l1+j]=(outbuf[l2+j]+outbuf[l1+j-1])/2;
|
|
4450 |
// }
|
|
4451 |
// }
|
|
4452 |
// for (int i=sizey-1;i<sizey;i++)
|
|
4453 |
// {
|
|
4454 |
// int l0=(i-1)*stride;
|
|
4455 |
// int l1=(i)*stride;
|
|
4456 |
// for (int j=0;j<1;j++)
|
|
4457 |
// {
|
|
4458 |
//
|
|
4459 |
// outbuf[l1+j]=(outbuf[l0+j]+outbuf[l1+j+1])/2;
|
|
4460 |
// }
|
|
4461 |
// for (int j=sizex-1;j<sizex;j++)
|
|
4462 |
// {
|
|
4463 |
// outbuf[l1+j]=(outbuf[l0+j]+outbuf[l1+j-1])/2;
|
|
4464 |
// }
|
|
4465 |
// }
|
|
4466 |
//
|
|
4467 |
// return sizex*sizey;
|
|
4468 |
// }
|
|
4469 |
template <typename T>
|
|
4470 |
int juanji2D3x3(T inbuf[], int sizex, int sizey, int stride, T outbuf[], T corebuf[3][3])
|
|
4471 |
{
|
|
4472 |
|
|
4473 |
for (int i=1;i<sizey-1;i++) //正常运算//内部区域
|
|
4474 |
{
|
|
4475 |
int l0=(i-1)*stride;
|
|
4476 |
int l1=(i)*stride;
|
|
4477 |
int l2=(i+1)*stride;
|
|
4478 |
for (int j=1;j<sizex-1;j++)
|
|
4479 |
{
|
|
4480 |
T a1,a2,a3;
|
|
4481 |
// __m256 m1,m2,m3;
|
|
4482 |
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4483 |
// m2=_mm256_loadu_ps(&corebuf);
|
|
4484 |
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
|
|
4485 |
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
|
4486 |
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
|
4487 |
outbuf[l1+j]=a1+a2+a3;
|
|
4488 |
}
|
|
4489 |
}
|
|
4490 |
for (int i=0;i<1;i++) //处理边缘,上边缘,不包括左上角和右上角;
|
|
4491 |
{
|
|
4492 |
// int l0=(i)*stride;
|
|
4493 |
int l1=(i)*stride;
|
|
4494 |
int l2=(i+1)*stride;
|
|
4495 |
for (int j=1;j<sizex-1;j++)
|
|
4496 |
{
|
|
4497 |
T a1,a2,a3;
|
|
4498 |
// __m256 m1,m2,m3;
|
|
4499 |
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4500 |
// m2=_mm256_loadu_ps(&corebuf);
|
|
4501 |
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];
|
|
4502 |
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
|
4503 |
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
|
4504 |
outbuf[l1+j]=a1+a2+a3;
|
|
4505 |
}
|
|
4506 |
}
|
|
4507 |
for (int i=sizey-1;i<sizey;i++) //下边缘,不包括左下角和右下角
|
|
4508 |
{
|
|
4509 |
int l0=(i-1)*stride;
|
|
4510 |
int l1=(i)*stride;
|
|
4511 |
// int l2=(i)*stride;
|
|
4512 |
|
|
4513 |
for (int j=1;j<sizex-1;j++)
|
|
4514 |
{
|
|
4515 |
T a1,a2,a3;
|
|
4516 |
// __m256 m1,m2,m3;
|
|
4517 |
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4518 |
// m2=_mm256_loadu_ps(&corebuf);
|
|
4519 |
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
|
|
4520 |
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
|
4521 |
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];
|
|
4522 |
outbuf[l1+j]=a1+a2+a3;
|
|
4523 |
}
|
|
4524 |
}
|
|
4525 |
for (int i=1;i<sizey-1;i++) //左边缘,不包括左上角和左下角
|
|
4526 |
{
|
|
4527 |
int l0=(i-1)*stride;
|
|
4528 |
int l1=(i)*stride;
|
|
4529 |
int l2=(i+1)*stride;
|
|
4530 |
for (int j=0;j<1;j++)
|
|
4531 |
{
|
|
4532 |
T a1,a2,a3;
|
|
4533 |
// __m256 m1,m2,m3;
|
|
4534 |
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4535 |
// m2=_mm256_loadu_ps(&corebuf);
|
|
4536 |
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];
|
|
4537 |
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];
|
|
4538 |
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];
|
|
4539 |
outbuf[l1+j]=a1+a2+a3;
|
|
4540 |
}
|
|
4541 |
}
|
|
4542 |
for (int i=1;i<sizey-1;i++) //右边缘,不包括右上角和右下角
|
|
4543 |
{
|
|
4544 |
int l0=(i-1)*stride;
|
|
4545 |
int l1=(i)*stride;
|
|
4546 |
int l2=(i+1)*stride;
|
|
4547 |
for (int j=sizex-1;j<sizex;j++)
|
|
4548 |
{
|
|
4549 |
T a1,a2,a3;
|
|
4550 |
// __m256 m1,m2,m3;
|
|
4551 |
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4552 |
// m2=_mm256_loadu_ps(&corebuf);
|
|
4553 |
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];
|
|
4554 |
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];
|
|
4555 |
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];
|
|
4556 |
outbuf[l1+j]=a1+a2+a3;
|
|
4557 |
}
|
|
4558 |
}
|
|
4559 |
//四个角
|
|
4560 |
for (int i=0;i<1;i++)
|
|
4561 |
{
|
|
4562 |
int l0=(i)*stride;
|
|
4563 |
int l1=(i)*stride;
|
|
4564 |
int l2=(i+1)*stride;
|
|
4565 |
for (int j=0;j<1;j++)
|
|
4566 |
{
|
|
4567 |
T a1,a2,a3;
|
|
4568 |
// __m256 m1,m2,m3;
|
|
4569 |
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4570 |
// m2=_mm256_loadu_ps(&corebuf);
|
|
4571 |
a1=inbuf[l0+j]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
|
|
4572 |
a2=inbuf[l1+j]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
|
|
4573 |
a3=inbuf[l2+j]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
|
|
4574 |
outbuf[l1+j]=a1+a2+a3;
|
|
4575 |
}
|
|
4576 |
for (int j=sizex-1;j<sizex;j++)
|
|
4577 |
{
|
|
4578 |
T a1,a2,a3;
|
|
4579 |
// __m256 m1,m2,m3;
|
|
4580 |
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4581 |
// m2=_mm256_loadu_ps(&corebuf);
|
|
4582 |
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
|
|
4583 |
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
|
|
4584 |
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
|
|
4585 |
outbuf[l1+j]=a1+a2+a3;
|
|
4586 |
}
|
|
4587 |
}
|
|
4588 |
for (int i=sizey-1;i<sizey;i++)
|
|
4589 |
{
|
|
4590 |
int l0=(i-1)*stride;
|
|
4591 |
int l1=(i)*stride;
|
|
4592 |
int l2=(i)*stride;
|
|
4593 |
for (int j=0;j<1;j++)
|
|
4594 |
{
|
|
4595 |
T a1,a2,a3;
|
|
4596 |
// __m256 m1,m2,m3;
|
|
4597 |
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4598 |
// m2=_mm256_loadu_ps(&corebuf);
|
|
4599 |
a1=inbuf[l0+j]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
|
|
4600 |
a2=inbuf[l1+j]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
|
|
4601 |
a3=inbuf[l2+j]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
|
|
4602 |
outbuf[l1+j]=a1+a2+a3;
|
|
4603 |
}
|
|
4604 |
for (int j=sizex-1;j<sizex;j++)
|
|
4605 |
{
|
|
4606 |
T a1,a2,a3;
|
|
4607 |
// __m256 m1,m2,m3;
|
|
4608 |
// m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4609 |
// m2=_mm256_loadu_ps(&corebuf);
|
|
4610 |
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
|
|
4611 |
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
|
|
4612 |
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
|
|
4613 |
outbuf[l1+j]=a1+a2+a3;
|
|
4614 |
}
|
|
4615 |
}
|
|
4616 |
|
|
4617 |
return sizex*sizey;
|
|
4618 |
}
|
|
4619 |
template<> int juanji2D3x3(float inbuf[], int sizex, int sizey, int stride, float outbuf[], float corebuf[3][3])
|
|
4620 |
{
|
|
4621 |
__m256 km1,km2,km3;
|
|
4622 |
km1=_mm256_loadu_ps(corebuf[0]);
|
|
4623 |
km2=_mm256_loadu_ps(corebuf[1]);
|
|
4624 |
km3=_mm256_loadu_ps(corebuf[2]);
|
|
4625 |
km1=_mm256_shuffle_ps(km2,km3,0x4e);
|
|
4626 |
// _mm256_rsqrt_ps()
|
|
4627 |
for (int i=1;i<sizey-1;i++) //正常运算
|
|
4628 |
{
|
|
4629 |
int l0=(i-1)*stride;
|
|
4630 |
int l1=(i)*stride;
|
|
4631 |
int l2=(i+1)*stride;
|
|
4632 |
for (int j=1;j<sizex-1;j++)
|
|
4633 |
{
|
|
4634 |
float a1,a2,a3;
|
|
4635 |
// __m256 m1,m2,m3,m4,m5,m6;
|
|
4636 |
// m1=_mm256_loadu_ps(&inbuf[l0+j-1]);
|
|
4637 |
// m2=_mm256_loadu_ps(&inbuf[l1+j-1]);
|
|
4638 |
// m4=_mm256_mul_ps(m1,km1);
|
|
4639 |
// m3=_mm256_loadu_ps(&inbuf[l2+j-1]);
|
|
4640 |
// m5=_mm256_mul_ps(m2,km2);
|
|
4641 |
// m6=_mm256_mul_ps(m3,km3);
|
|
4642 |
// m1=_mm256_add_ps(m4,m5);
|
|
4643 |
// m1=_mm256_add_ps(m1,m6);
|
|
4644 |
// a1=m1.m256_f32[0];a2=m1.m256_f32[1];a3=m1.m256_f32[2];
|
|
4645 |
a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
|
|
4646 |
|
|
4647 |
a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
|
|
4648 |
a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
|
4649 |
|
|
4650 |
outbuf[l1+j]=a1+a2+a3;
|
|
4651 |
}
|
|
4652 |
}
|
|
4653 |
for (int i=0;i<1;i++) //处理边缘,所有的边缘等于0;
|
|
4654 |
{
|
|
4655 |
int l1=(i)*stride;
|
|
4656 |
for (int j=0;j<sizex;j++)
|
|
4657 |
{
|
|
4658 |
outbuf[l1+j]=0;
|
|
4659 |
}
|
|
4660 |
}
|
|
4661 |
for (int i=sizey-1;i<sizey;i++)
|
|
4662 |
{
|
|
4663 |
int l1=(i)*stride;
|
|
4664 |
for (int j=0;j<sizex;j++)
|
|
4665 |
{
|
|
4666 |
outbuf[l1+j]=0;
|
|
4667 |
}
|
|
4668 |
}
|
|
4669 |
for (int i=0;i<sizey;i++)
|
|
4670 |
{
|
|
4671 |
int l1=(i)*stride;
|
|
4672 |
for (int j=0;j<1;j++)
|
|
4673 |
{
|
|
4674 |
outbuf[l1+j]=0;
|
|
4675 |
}
|
|
4676 |
}
|
|
4677 |
for (int i=0;i<sizey;i++)
|
|
4678 |
{
|
|
4679 |
int l1=(i)*stride;
|
|
4680 |
for (int j=sizex-1;j<sizex;j++)
|
|
4681 |
{
|
|
4682 |
outbuf[l1+j]=0;
|
|
4683 |
}
|
|
4684 |
}
|
|
4685 |
return sizex*sizey;
|
|
4686 |
}
|
|
4687 |
void dummy1(void)
|
|
4688 |
{
|
|
4689 |
double a[1];
|
|
4690 |
double b[3][3];
|
|
4691 |
juanji2D3x3(a,1,1,1,a,b);
|
|
4692 |
float c[1];
|
|
4693 |
float d[3][3];
|
|
4694 |
juanji2D3x3(c,1,1,1,c,d);
|
|
4695 |
}
|
|
4696 |
|
|
4697 |
int DCT(double pt[], double dpt[],int size,int start,int end)
|
|
4698 |
{
|
|
4699 |
if (size&1) {size=size-1;}
|
|
4700 |
dpt[0]=0;
|
|
4701 |
for (int j=0;j<size;j++)
|
|
4702 |
{
|
|
4703 |
dpt[0]+=pt[j];
|
|
4704 |
}
|
|
4705 |
dpt[0]/=sqrt(double(size));
|
|
4706 |
for (int i=start;i<=end;i++)
|
|
4707 |
{
|
|
4708 |
dpt[i]=0;
|
|
4709 |
for (int j=0;j<size;j++)
|
|
4710 |
{
|
|
4711 |
dpt[i]+=pt[j]*cos((2*j+1)*i*3.1415926535897932384626433/(2*size));
|
|
4712 |
}
|
|
4713 |
dpt[i]/=sqrt(double(size)/2);
|
|
4714 |
}
|
|
4715 |
return 1;
|
|
4716 |
}
|
|
4717 |
|
|
4718 |
int DCT(float pt[], float dpt[],int size,int start,int end)
|
|
4719 |
{
|
|
4720 |
if (size&1) {size=size-1;}
|
|
4721 |
dpt[0]=0;
|
|
4722 |
for (int j=0;j<size;j++)
|
|
4723 |
{
|
|
4724 |
dpt[0]+=pt[j];
|
|
4725 |
}
|
|
4726 |
dpt[0]/=sqrt(float(size));
|
|
4727 |
for (int i=start;i<end;i++)
|
|
4728 |
{
|
|
4729 |
dpt[i]=0;
|
|
4730 |
for (int j=0;j<size;j++)
|
|
4731 |
{
|
|
4732 |
dpt[i]+=pt[j]*cos((2*j+1)*i*3.1415926535897932384626433f/2/size);
|
|
4733 |
}
|
|
4734 |
dpt[i]/=sqrt(float(size)/2);
|
|
4735 |
}
|
|
4736 |
return 1;
|
|
4737 |
}
|
|
4738 |
|
|
4739 |
int FDCT(double pt[], double dpt[],int size,int start,int end)
|
|
4740 |
{
|
|
4741 |
if (size&1) {size=size-1;}
|
|
4742 |
double * costab=new double[4*size+4];
|
|
4743 |
for (int i=0;i<=size;i++)
|
|
4744 |
{//计算余弦表
|
|
4745 |
double result1=cos(i*3.1415926535897932384626433/2/size);
|
|
4746 |
costab[i]=result1;
|
|
4747 |
costab[2*size-i]=-result1;
|
|
4748 |
costab[2*size+i]=-result1;
|
|
4749 |
costab[4*size-i]=result1;
|
|
4750 |
}
|
|
4751 |
|
|
4752 |
dpt[0]=0;
|
|
4753 |
for (int j=0;j<size;j++)
|
|
4754 |
{
|
|
4755 |
dpt[0]+=pt[j];
|
|
4756 |
}
|
|
4757 |
dpt[0]/=sqrt(double(size));
|
|
4758 |
for (int i=start;i<=end;i++)
|
|
4759 |
{
|
|
4760 |
dpt[i]=0;
|
|
4761 |
for (int j=0;j<size;j++)
|
|
4762 |
{
|
|
4763 |
dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)];
|
|
4764 |
}
|
|
4765 |
dpt[i]/=sqrt(double(size)/2);
|
|
4766 |
}
|
|
4767 |
delete [] costab;
|
|
4768 |
return 1;
|
|
4769 |
}
|
|
4770 |
|
|
4771 |
int FDCT(float pt[], float dpt[],int size,int start,int end)
|
|
4772 |
{
|
|
4773 |
if (size&1) {size=size-1;}
|
|
4774 |
dpt[0]=0;
|
|
4775 |
float * costab=new float[4*size+4];
|
|
4776 |
for (int i=0;i<size;i++)
|
|
4777 |
{//计算余弦表
|
|
4778 |
float result1=cosf(i*3.1415926535897932384626433f/2/size);
|
|
4779 |
costab[i]=result1;
|
|
4780 |
costab[2*size-i]=-result1;
|
|
4781 |
costab[2*size+i]=-result1;
|
|
4782 |
costab[4*size-i]=result1;
|
|
4783 |
}
|
|
4784 |
|
|
4785 |
for (int j=0;j<size;j++)
|
|
4786 |
{
|
|
4787 |
dpt[0]+=pt[j];
|
|
4788 |
}
|
|
4789 |
dpt[0]/=sqrt(float(size));
|
|
4790 |
for (int i=start;i<end;i++)
|
|
4791 |
{
|
|
4792 |
dpt[i]=0;
|
|
4793 |
for (int j=0;j<size;j++)
|
|
4794 |
{
|
|
4795 |
dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)]; //cos((2*j+1)*i*3.1415926f/2/size);
|
|
4796 |
}
|
|
4797 |
dpt[i]/=sqrt(float(size)/2);
|
|
4798 |
}
|
|
4799 |
delete [] costab;
|
|
4800 |
return 1;
|
|
4801 |
}
|
|
4802 |
|
|
4803 |
int FFDCT(double pt[], double dpt[],int size,int start,int end)
|
|
4804 |
{
|
|
4805 |
if (size&1) {size=size-1;}
|
|
4806 |
double * costab=new double[4*size+4];
|
|
4807 |
for (int i=0;i<size;i++)
|
|
4808 |
{//计算余弦表
|
|
4809 |
double result1=cos(i*3.1415926535897932384626433/2/size);
|
|
4810 |
costab[i]=result1;
|
|
4811 |
costab[2*size-i]=-result1;
|
|
4812 |
costab[2*size+i]=-result1;
|
|
4813 |
costab[4*size-i]=result1;
|
|
4814 |
}
|
|
4815 |
|
|
4816 |
dpt[0]=0;
|
|
4817 |
for (int j=0;j<size;j++)
|
|
4818 |
{
|
|
4819 |
dpt[0]+=pt[j];
|
|
4820 |
}
|
|
4821 |
dpt[0]/=sqrt(double(size));
|
|
4822 |
for (int i=start;i<=end;i++)
|
|
4823 |
{
|
|
4824 |
dpt[i]=0;
|
|
4825 |
int j;
|
|
4826 |
for (j=0;j<size-7;j+=8)
|
|
4827 |
{
|
|
4828 |
double temp[8];
|
|
4829 |
temp[0]=pt[j]*costab[(2*j+1)*i%(4*size)];
|
|
4830 |
temp[1]=pt[j+1]*costab[(2*j+3)*i%(4*size)];
|
|
4831 |
temp[2]=pt[j+2]*costab[(2*j+5)*i%(4*size)];
|
|
4832 |
temp[3]=pt[j+3]*costab[(2*j+7)*i%(4*size)];
|
|
4833 |
temp[4]=pt[j+4]*costab[(2*j+9)*i%(4*size)];
|
|
4834 |
temp[5]=pt[j+5]*costab[(2*j+11)*i%(4*size)];
|
|
4835 |
temp[6]=pt[j+6]*costab[(2*j+13)*i%(4*size)];
|
|
4836 |
temp[7]=pt[j+7]*costab[(2*j+15)*i%(4*size)];
|
|
4837 |
|
|
4838 |
dpt[i]+=temp[0]+temp[1]+temp[2]+temp[3]+temp[4]+temp[5]+temp[6]+temp[7];
|
|
4839 |
}
|
|
4840 |
for (;j<size;j++)
|
|
4841 |
{
|
|
4842 |
dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)]; //cos((2*j+1)*i*3.1415926f/2/size);
|
|
4843 |
}
|
|
4844 |
dpt[i]/=sqrt(double(size)/2);
|
|
4845 |
}
|
|
4846 |
delete [] costab;
|
|
4847 |
return 1;
|
|
4848 |
}
|
|
4849 |
|
|
4850 |
int FFDCT(float pt[], float dpt[],int size,int start,int end)
|
|
4851 |
{
|
|
4852 |
if (size&1) {size=size-1;}
|
|
4853 |
float * costab=new float[4*size];
|
|
4854 |
for (int i=0;i<size;i++)
|
|
4855 |
{//计算余弦表
|
|
4856 |
float result1=cosf(i*3.1415926535897932384626433f/2/size);
|
|
4857 |
costab[i]=result1;
|
|
4858 |
costab[2*size-1-i]=-result1;
|
|
4859 |
costab[2*size+i]=-result1;
|
|
4860 |
costab[4*size-1-i]=result1;
|
|
4861 |
}
|
|
4862 |
|
|
4863 |
dpt[0]=0;
|
|
4864 |
for (int j=0;j<size;j++)
|
|
4865 |
{
|
|
4866 |
dpt[0]+=pt[j];
|
|
4867 |
}
|
|
4868 |
dpt[0]/=sqrt(float(size));
|
|
4869 |
for (int i=start;i<=end;i++)
|
|
4870 |
{
|
|
4871 |
dpt[i]=0;
|
|
4872 |
int j;
|
|
4873 |
for (j=0;j<size-7;j+=8)
|
|
4874 |
{
|
|
4875 |
_CRT_ALIGN(32) float temp[8];
|
|
4876 |
// _CRT_ALIGN(32) float results[8];
|
|
4877 |
temp[0]=pt[j]*costab[(2*j+1)*i%(4*size)];
|
|
4878 |
temp[1]=pt[j+1]*costab[(2*j+3)*i%(4*size)];
|
|
4879 |
temp[2]=pt[j+2]*costab[(2*j+5)*i%(4*size)];
|
|
4880 |
temp[3]=pt[j+3]*costab[(2*j+7)*i%(4*size)];
|
|
4881 |
temp[4]=pt[j+4]*costab[(2*j+9)*i%(4*size)];
|
|
4882 |
temp[5]=pt[j+5]*costab[(2*j+11)*i%(4*size)];
|
|
4883 |
temp[6]=pt[j+6]*costab[(2*j+13)*i%(4*size)];
|
|
4884 |
temp[7]=pt[j+7]*costab[(2*j+15)*i%(4*size)];
|
|
4885 |
|
|
4886 |
/*
|
|
4887 |
results[0]=costab[(2*j+1)*i%(2*size)];
|
|
4888 |
results[1]=costab[(2*j+3)*i%(2*size)];
|
|
4889 |
results[2]=costab[(2*j+5)*i%(2*size)];
|
|
4890 |
results[3]=costab[(2*j+6)*i%(2*size)];
|
|
4891 |
results[4]=costab[(2*j+9)*i%(2*size)];
|
|
4892 |
results[5]=costab[(2*j+11)*i%(2*size)];
|
|
4893 |
results[6]=costab[(2*j+13)*i%(2*size)];
|
|
4894 |
results[7]=costab[(2*j+15)*i%(2*size)];
|
|
4895 |
temp[0]=pt[j]*results[0];
|
|
4896 |
temp[1]=pt[j+1]*results[1];
|
|
4897 |
temp[2]=pt[j+2]*results[2];
|
|
4898 |
temp[3]=pt[j+3]*results[3];
|
|
4899 |
temp[4]=pt[j+4]*results[4];
|
|
4900 |
temp[5]=pt[j+5]*results[5];
|
|
4901 |
temp[6]=pt[j+6]*results[6];
|
|
4902 |
temp[7]=pt[j+7]*results[7];
|
|
4903 |
*/
|
|
4904 |
// __m256 a,b,c;
|
|
4905 |
// a=_mm256_loadu_ps(&pt[j]);
|
|
4906 |
// b=_mm256_loadu_ps(results);
|
|
4907 |
// c=_mm256_mul_ps(a,b);
|
|
4908 |
// _mm256_storeu_ps(temp,c);
|
|
4909 |
dpt[i]+=temp[0]+temp[1]+temp[2]+temp[3]+temp[4]+temp[5]+temp[6]+temp[7];
|
|
4910 |
// dpt[i]+=((temp[0]+temp[1])+(temp[2]+temp[3]))+((temp[4]+temp[5])+(temp[6]+temp[7]));
|
|
4911 |
}
|
|
4912 |
for (;j<size;j++)
|
|
4913 |
{
|
|
4914 |
dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)]; //cos((2*j+1)*i*3.1415926f/2/size);
|
|
4915 |
}
|
|
4916 |
dpt[i]/=sqrt(float(size)/2);
|
|
4917 |
}
|
|
4918 |
delete [] costab;
|
|
4919 |
return 1;
|
|
4920 |
}
|
|
4921 |
|
|
4922 |
/*
|
|
4923 |
int juanji2D3x3(float inbuf[], int sizex, int sizey, int stride, float outbuf[], float corebuf[3][3])
|
|
4924 |
{
|
|
4925 |
|
|
4926 |
for (int i=1;i<sizey-1;i++) //正常运算
|
|
4927 |
{
|
|
4928 |
int l0=(i-1)*stride;
|
|
4929 |
int l1=(i)*stride;
|
|
4930 |
int l2=(i+1)*stride;
|
|
4931 |
for (int j=1;j<sizex-1;j++)
|
|
4932 |
{
|
|
4933 |
outbuf[l1+j]=
|
|
4934 |
inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2]+
|
|
4935 |
inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2]+
|
|
4936 |
inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
|
|
4937 |
}
|
|
4938 |
}
|
|
4939 |
for (int i=0;i<1;i++) //处理边缘,所有的边缘等于0;
|
|
4940 |
{
|
|
4941 |
int l1=(i)*stride;
|
|
4942 |
for (int j=0;j<sizex;j++)
|
|
4943 |
{
|
|
4944 |
outbuf[l1+j]=0;
|
|
4945 |
}
|
|
4946 |
}
|
|
4947 |
for (int i=sizey-1;i<sizey;i++)
|
|
4948 |
{
|
|
4949 |
int l1=(i)*stride;
|
|
4950 |
for (int j=0;j<sizex;j++)
|
|
4951 |
{
|
|
4952 |
outbuf[l1+j]=0;
|
|
4953 |
}
|
|
4954 |
}
|
|
4955 |
for (int i=0;i<sizey;i++)
|
|
4956 |
{
|
|
4957 |
int l1=(i)*stride;
|
|
4958 |
for (int j=0;j<1;j++)
|
|
4959 |
{
|
|
4960 |
outbuf[l1+j]=0;
|
|
4961 |
}
|
|
4962 |
}
|
|
4963 |
for (int i=0;i<sizey;i++)
|
|
4964 |
{
|
|
4965 |
int l1=(i)*stride;
|
|
4966 |
for (int j=sizex-1;j<sizex;j++)
|
|
4967 |
{
|
|
4968 |
outbuf[l1+j]=0;
|
|
4969 |
}
|
|
4970 |
}
|
|
4971 |
return sizex*sizey;
|
|
4972 |
}
|
|
4973 |
*/
|
|
4974 |
int nihe(CPoint pt5[100],int pt5total,int pt5valid[100])
|
|
4975 |
{
|
|
4976 |
int i,j,k;//,l;
|
|
4977 |
int startpt,endpt;
|
|
4978 |
double angle1,angle2;
|
|
4979 |
double distance,intercept;
|
|
4980 |
double maxintercept=3;
|
|
4981 |
double totalintercept;
|
|
4982 |
int validpts;
|
|
4983 |
int maxstartpt,maxendpt;
|
|
4984 |
int maxvalidpts;
|
|
4985 |
double minintercept;
|
|
4986 |
maxvalidpts=0;
|
|
4987 |
int ptvalid[100];
|
|
4988 |
maxstartpt=0;
|
|
4989 |
maxendpt=1;
|
|
4990 |
|
|
4991 |
for (i=0;i<pt5total;i++)
|
|
4992 |
{
|
|
4993 |
ptvalid[i]=0;
|
|
4994 |
}
|
|
4995 |
|
|
4996 |
for (i=0;i<pt5total-1;i++)
|
|
4997 |
{
|
|
4998 |
startpt=i;
|
|
4999 |
ptvalid[i]=1;
|
|
5000 |
for (j=i+1;j<pt5total;j++)
|
|
5001 |
{
|
|
5002 |
validpts=0;
|
|
5003 |
endpt=j;
|
|
5004 |
angle1=atan(((double)pt5[i].x-pt5[j].x)/((double)pt5[i].y-pt5[j].y));
|
|
5005 |
totalintercept=0;
|
|
5006 |
ptvalid[j]=1;
|
|
5007 |
for (k=0;k<pt5total;k++)
|
|
5008 |
{
|
|
5009 |
if (k==i) {continue;}
|
|
5010 |
if (k==j) {continue;}
|
|
5011 |
angle2=atan(((double)pt5[i].x-pt5[k].x)/((double)pt5[i].y-pt5[k].y));
|
|
5012 |
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));
|
|
5013 |
intercept=distance*sin(abs(angle2-angle1));
|
|
5014 |
if (intercept<maxintercept)
|
|
5015 |
{
|
|
5016 |
ptvalid[k]=1;
|
|
5017 |
validpts++;
|
|
5018 |
totalintercept+=intercept;
|
|
5019 |
}
|
|
5020 |
else
|
|
5021 |
{
|
|
5022 |
ptvalid[k]=0;
|
|
5023 |
}
|
|
5024 |
}
|
|
5025 |
if ((validpts>maxvalidpts)||(validpts==maxvalidpts&&totalintercept<minintercept))
|
|
5026 |
{
|
|
5027 |
maxvalidpts=validpts;
|
|
5028 |
maxstartpt=startpt;
|
|
5029 |
maxendpt=endpt;
|
|
5030 |
minintercept=totalintercept;
|
|
5031 |
for (k=0;k<pt5total;k++)
|
|
5032 |
{
|
|
5033 |
pt5valid[k]=ptvalid[k];
|
|
5034 |
}
|
|
5035 |
|
|
5036 |
}
|
|
5037 |
ptvalid[j]=0;
|
|
5038 |
}
|
|
5039 |
ptvalid[i]=0;
|
|
5040 |
}
|
|
5041 |
return MAKELONG(maxstartpt,maxendpt);
|
|
5042 |
}
|
|
5043 |
|
|
5044 |
UINT __cdecl memcpyThread(LPVOID pParam)
|
|
5045 |
{
|
|
5046 |
MemcpyThreadDataStruct * p1=(MemcpyThreadDataStruct *)pParam;
|
|
5047 |
void * dest2,*src2;
|
|
5048 |
unsigned long size_t2;
|
|
5049 |
dest2=p1->dest;
|
|
5050 |
src2=p1->src;
|
|
5051 |
size_t2=p1->size;
|
|
5052 |
X_aligned_memcpy_sse2(dest2, src2, size_t2);
|
|
5053 |
p1->done=1;
|
|
5054 |
return 1000;
|
|
5055 |
}
|
|
5056 |
|
|
5057 |
void fastmemcpy(void* dest, const void* src, const unsigned long size_t)
|
|
5058 |
{
|
|
5059 |
void * dest2,* src2;
|
|
5060 |
unsigned long size_t2;
|
|
5061 |
src2=(void *)src;
|
|
5062 |
dest2=dest;
|
|
5063 |
size_t2=size_t;
|
|
5064 |
if (((UINT)dest)&0xf)
|
|
5065 |
{
|
|
5066 |
UINT delta;
|
|
5067 |
|
|
5068 |
dest2=(void *)((((UINT)dest)+15)&0xfffffff0);
|
|
5069 |
delta=(UINT)dest2-(UINT)dest;
|
|
5070 |
size_t2-=delta;
|
|
5071 |
src=(void *)((UINT(src))+delta);
|
|
5072 |
}
|
|
5073 |
|
|
5074 |
X_aligned_memcpy_sse2(dest2, src2, size_t2);
|
|
5075 |
}
|
|
5076 |
void fastmemcpyMT(void* dest, const void* src, const unsigned long size_t)
|
|
5077 |
{
|
|
5078 |
MemcpyThreadDataStruct threaddata[2];
|
|
5079 |
threaddata[0].src=(void *)src;
|
|
5080 |
threaddata[0].dest=dest;
|
|
5081 |
threaddata[0].size=size_t/2;
|
|
5082 |
threaddata[0].done=0;
|
|
5083 |
|
|
5084 |
threaddata[1].src=(unsigned char *)src+size_t/2;
|
|
5085 |
threaddata[1].dest=(unsigned char *)dest+size_t/2;
|
|
5086 |
threaddata[1].size=size_t/2;
|
|
5087 |
threaddata[1].done=0;
|
|
5088 |
AfxBeginThread(memcpyThread,LPVOID(&threaddata[0]));
|
|
5089 |
AfxBeginThread(memcpyThread,LPVOID(&threaddata[1]));
|
|
5090 |
while(1)
|
|
5091 |
{
|
|
5092 |
if (threaddata[0].done&&threaddata[1].done) {break;}
|
|
5093 |
}
|
|
5094 |
|
|
5095 |
|
|
5096 |
}
|
|
5097 |
|
|
5098 |
int GetLineSegmentPart(double startx, double starty, double endx, double endy, double numerator, double denominator, double & x1, double & y1)
|
|
5099 |
{
|
|
5100 |
|
|
5101 |
x1=(startx*(denominator-numerator)+endx*numerator)/denominator;
|
|
5102 |
y1=(starty*(denominator-numerator)+endy*numerator)/denominator;
|
|
5103 |
return 1;
|
|
5104 |
}
|
|
5105 |
|
|
5106 |
double LineSegmentDirection(PointD pt1,PointD pt2,PointD pt3)
|
|
5107 |
{
|
|
5108 |
PointD d1,d2;
|
|
5109 |
d1=pt3-pt1;d2=pt2-pt1;
|
|
5110 |
return d1.x*d2.y-d1.y*d2.x;
|
|
5111 |
|
|
5112 |
}
|
|
5113 |
int IsOnLineSegment(MyLineSegment linesegment1,PointD pt1)
|
|
5114 |
{
|
|
5115 |
double x_min,x_max,y_min,y_max;
|
|
5116 |
if (linesegment1.start.x<linesegment1.end.x)
|
|
5117 |
{
|
|
5118 |
x_min=linesegment1.start.x;
|
|
5119 |
x_max=linesegment1.end.x;
|
|
5120 |
}
|
|
5121 |
else
|
|
5122 |
{
|
|
5123 |
x_min=linesegment1.end.x;
|
|
5124 |
x_max=linesegment1.start.x;
|
|
5125 |
}
|
|
5126 |
if (linesegment1.start.y<linesegment1.end.y)
|
|
5127 |
{
|
|
5128 |
y_min=linesegment1.start.y;
|
|
5129 |
y_max=linesegment1.end.y;
|
|
5130 |
}
|
|
5131 |
else
|
|
5132 |
{
|
|
5133 |
y_min=linesegment1.end.y;
|
|
5134 |
y_max=linesegment1.start.y;
|
|
5135 |
}
|
|
5136 |
if (pt1.x<x_min||pt1.x>x_max||pt1.y<y_min||pt1.y>y_max)
|
|
5137 |
return false;
|
|
5138 |
else return true;
|
|
5139 |
}
|
|
5140 |
|
|
5141 |
int IsLineSegmentCross(MyLineSegment linesegment1, MyLineSegment linesegment2)
|
|
5142 |
{
|
|
5143 |
PointD pt1,pt2,pt3,pt4;
|
|
5144 |
pt1=linesegment1.start;pt2=linesegment1.end;
|
|
5145 |
pt3=linesegment2.start;pt4=linesegment2.end;
|
|
5146 |
double d1,d2,d3,d4;
|
|
5147 |
d1=LineSegmentDirection(pt3,pt4,pt1);
|
|
5148 |
d2=LineSegmentDirection(pt3,pt4,pt2);
|
|
5149 |
d3=LineSegmentDirection(pt1,pt2,pt3);
|
|
5150 |
d4=LineSegmentDirection(pt1,pt2,pt4);
|
|
5151 |
if (d1*d2<0&&d3*d4<0)
|
|
5152 |
return true;
|
|
5153 |
else if (d1==0&&IsOnLineSegment(linesegment2,pt1)) return true;
|
|
5154 |
else if (d2==0&&IsOnLineSegment(linesegment2,pt2)) return true;
|
|
5155 |
else if (d3==0&&IsOnLineSegment(linesegment1,pt3)) return true;
|
|
5156 |
else if (d4==0&&IsOnLineSegment(linesegment1,pt4)) return true;
|
|
5157 |
else return false;
|
|
5158 |
}
|
|
5159 |
/*
|
|
5160 |
int IsLineSegmentCross(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
|
|
5161 |
{
|
|
5162 |
PointD pt1,pt2,pt3,pt4;
|
|
5163 |
pt1=PointD(x1,y1);pt2=PointD(x2,y2);
|
|
5164 |
pt3=PointD(x3,y3);pt4=PointD(x4,y4);
|
|
5165 |
double d1,d2,d3,d4;
|
|
5166 |
d1=LineSegmentDirection(pt3,pt4,pt1);
|
|
5167 |
d2=LineSegmentDirection(pt3,pt4,pt2);
|
|
5168 |
d3=LineSegmentDirection(pt1,pt2,pt3);
|
|
5169 |
d4=LineSegmentDirection(pt1,pt2,pt4);
|
|
5170 |
if (d1*d2<0&&d3*d4<0)
|
|
5171 |
return true;
|
|
5172 |
else if (d1==0&&IsOnLineSegment(linesegment2,pt1)) return true;
|
|
5173 |
else if (d2==0&&IsOnLineSegment(linesegment2,pt2)) return true;
|
|
5174 |
else if (d3==0&&IsOnLineSegment(linesegment1,pt3)) return true;
|
|
5175 |
else if (d4==0&&IsOnLineSegment(linesegment1,pt4)) return true;
|
|
5176 |
else return false;
|
|
5177 |
return false;
|
|
5178 |
}
|
|
5179 |
*/
|
|
5180 |
int Canny算法()
|
|
5181 |
{
|
|
5182 |
return 0;
|
|
5183 |
};
|
|
5184 |
|
|
5185 |
int Hough(MyImage& img1,stHoughResult res[],int MaxFound, double Threshold,int starta,int enda)
|
|
5186 |
{
|
|
5187 |
const int hough_space=256;
|
|
5188 |
int width=img1.Width;
|
|
5189 |
int height=img1.Height;
|
|
5190 |
int stride=img1.Stride;
|
|
5191 |
|
|
5192 |
int centerX=width/2;
|
|
5193 |
int centerY=height/2;
|
|
5194 |
double hough_interval=3.1415926535897932384626433/(double)hough_space;
|
|
5195 |
|
|
5196 |
int maxL=max(width,height);
|
|
5197 |
int max_length=(int)(1.41421356237*maxL);
|
|
5198 |
int hough_strides=(max_length+3)&0xfffffffc;
|
|
5199 |
unsigned char *pixels=(unsigned char *)img1.GetBuffer();
|
|
5200 |
/*
|
|
5201 |
//建立特征点的集合
|
|
5202 |
int TotalPixel=0;
|
|
5203 |
Point ptx[9999];
|
|
5204 |
unsigned char score1[9999];
|
|
5205 |
for (int i=0;i<height;i++)
|
|
5206 |
{
|
|
5207 |
for (int j=0;j<width;j++)
|
|
5208 |
{
|
|
5209 |
if (pixels[i*stride+j]==0) continue;
|
|
5210 |
if (TotalPixel<9999-1)
|
|
5211 |
{
|
|
5212 |
ptx[TotalPixel].X=j;
|
|
5213 |
ptx[TotalPixel].Y=i;
|
|
5214 |
score1[TotalPixel]=pixels[i*stride+j];
|
|
5215 |
TotalPixel++;
|
|
5216 |
}
|
|
5217 |
}
|
|
5218 |
}
|
|
5219 |
*/
|
|
5220 |
//建立参数空间
|
|
5221 |
int *hough_2d=new int[hough_space*hough_strides];
|
|
5222 |
//参数空间清零
|
|
5223 |
for (int i=0;i<hough_space;i++)
|
|
5224 |
{
|
|
5225 |
for (int j=0;j<max_length;j++)
|
|
5226 |
{
|
|
5227 |
hough_2d[i*hough_strides+j]=0;
|
|
5228 |
}
|
|
5229 |
}
|
|
5230 |
int minb=999,maxb=0;
|
|
5231 |
//像素映射到参数空间
|
|
5232 |
for (int i=0;i<height;i++)
|
|
5233 |
{
|
|
5234 |
int n=i*stride;
|
|
5235 |
for (int j=0;j<width;j++)
|
|
5236 |
{
|
|
5237 |
unsigned char pixel=pixels[n+j];
|
|
5238 |
if (pixel==0) continue;
|
|
5239 |
int maxk=0;
|
|
5240 |
for (int cell=starta;cell<enda;cell++)
|
|
5241 |
{
|
|
5242 |
maxk=(int)((j-centerX)*cos(cell*hough_interval-Pi/4)+(i-centerY)*sin(cell*hough_interval-Pi/4)+max_length/2);
|
|
5243 |
//maxk+=max_length/2;
|
|
5244 |
if (maxk>maxb) {maxb=maxk;}
|
|
5245 |
if (maxk<minb) {minb=maxk;}
|
|
5246 |
if (maxk<0||(maxk>=max_length))
|
|
5247 |
{
|
|
5248 |
continue;
|
|
5249 |
}
|
|
5250 |
hough_2d[cell*hough_strides+maxk]+=pixel;
|
|
5251 |
}
|
|
5252 |
|
|
5253 |
}
|
|
5254 |
}
|
|
5255 |
int max_hough=0;
|
|
5256 |
int max_x=0,max_y=0;
|
|
5257 |
//参数空间找最大值
|
|
5258 |
for (int i=starta;i<enda/*hough_space*/;i++)
|
|
5259 |
{
|
|
5260 |
for (int j=1;j<max_length-1;j++)
|
|
5261 |
{
|
|
5262 |
int thissum=0;
|
|
5263 |
for (int k=-1;k<2;k++)
|
|
5264 |
{
|
|
5265 |
for (int l=-1;l<2;l++)
|
|
5266 |
{
|
|
5267 |
thissum+=hough_2d[i*hough_strides+j];
|
|
5268 |
}
|
|
5269 |
}
|
|
5270 |
if (thissum>max_hough)
|
|
5271 |
{
|
|
5272 |
max_hough=thissum;
|
|
5273 |
max_x=j;max_y=i;
|
|
5274 |
}
|
|
5275 |
}
|
|
5276 |
}
|
|
5277 |
//找极值
|
|
5278 |
int totalfound=0;
|
|
5279 |
res[totalfound].Pt=PointD(max_y,max_x-max_length/2);
|
|
5280 |
res[totalfound].Score=max_hough;
|
|
5281 |
totalfound++;
|
|
5282 |
for (int i=starta+1;i<enda-1 /*hough_space-1*/;i++)
|
|
5283 |
{
|
|
5284 |
for (int j=1;j<max_length-1;j++)
|
|
5285 |
{
|
|
5286 |
int nofound=0;
|
|
5287 |
int thissum=0;
|
|
5288 |
for (int k=-1;k<2;k++)
|
|
5289 |
{
|
|
5290 |
for (int l=-1;l<2;l++)
|
|
5291 |
{
|
|
5292 |
thissum+=hough_2d[i*hough_strides+j];
|
|
5293 |
}
|
|
5294 |
}
|
|
5295 |
if (thissum<Threshold) continue;
|
|
5296 |
for (int k=-1;k<2;k++)
|
|
5297 |
{
|
|
5298 |
for (int l=-1;l<2;l++)
|
|
5299 |
{
|
|
5300 |
if (k==0&&l==0) continue;
|
|
5301 |
if (hough_2d[i*hough_strides+j]<hough_2d[(i+k)*hough_strides+(j+l)])
|
|
5302 |
{
|
|
5303 |
nofound=1;
|
|
5304 |
break;
|
|
5305 |
}
|
|
5306 |
}
|
|
5307 |
if (nofound) break;
|
|
5308 |
}
|
|
5309 |
if (nofound) continue; //found but not peak
|
|
5310 |
if (totalfound<MaxFound-1)
|
|
5311 |
{
|
|
5312 |
res[totalfound].Pt=PointD(i,j-max_length/2);
|
|
5313 |
res[totalfound].Score=thissum;
|
|
5314 |
totalfound++;
|
|
5315 |
if (totalfound>=MaxFound) break;
|
|
5316 |
}
|
|
5317 |
}
|
|
5318 |
}
|
|
5319 |
/*
|
|
5320 |
//转换到图像显示
|
|
5321 |
char factor=max_hough/127;
|
|
5322 |
if (factor<1) {factor=1;}
|
|
5323 |
if (max_hough<1) {max_hough=1;}
|
|
5324 |
unsigned char *hough_2d2=new unsigned char[hough_space*hough_strides];
|
|
5325 |
int kk;
|
|
5326 |
for (int i=0;i<hough_space;i++)
|
|
5327 |
{
|
|
5328 |
for (int j=0;j<max_length;j++)
|
|
5329 |
{
|
|
5330 |
kk=hough_2d[i*hough_strides+j]*255*8/max_hough;
|
|
5331 |
hough_2d2[i*hough_strides+j]=kk;
|
|
5332 |
}
|
|
5333 |
}
|
|
5334 |
//保存图像
|
|
5335 |
// SaveBufferToBmpFile(hough_2d2,max_length,hough_space,hough_strides,_T("d:\\1\\Hough001.bmp"));
|
|
5336 |
delete [] hough_2d2;
|
|
5337 |
// vector <int> a;
|
|
5338 |
//*/
|
|
5339 |
delete [] hough_2d;
|
|
5340 |
return totalfound;
|
|
5341 |
return 0;
|
|
5342 |
}
|
|
5343 |
|
|
5344 |
int NewHough(MyImage& img1,stHoughResult res[],int MaxFound, double Threshold,int starta,int enda)
|
|
5345 |
{
|
|
5346 |
const int hough_space=256;
|
|
5347 |
int width=img1.Width;
|
|
5348 |
int height=img1.Height;
|
|
5349 |
int stride=img1.Stride;
|
|
5350 |
|
|
5351 |
int centerX=width/2;
|
|
5352 |
int centerY=height/2;
|
|
5353 |
double hough_interval=3.1415926535897932384626433/(double)hough_space;
|
|
5354 |
|
|
5355 |
int maxL=max(width,height);
|
|
5356 |
int max_length=(int)(1.41421356237*maxL);
|
|
5357 |
int hough_strides=(max_length+3)&0xfffffffc;
|
|
5358 |
unsigned char *pixels=(unsigned char *)img1.GetBuffer();
|
|
5359 |
|
|
5360 |
//建立特征点的集合
|
|
5361 |
int TotalPixel=0;
|
|
5362 |
Gdiplus::Point ptx[9999];
|
|
5363 |
unsigned char score1[9999];
|
|
5364 |
unsigned char used[9999];
|
|
5365 |
unsigned char used2[9999];
|
|
5366 |
for (int i=0;i<height;i++)
|
|
5367 |
{
|
|
5368 |
for (int j=0;j<width;j++)
|
|
5369 |
{
|
|
5370 |
if (pixels[i*stride+j]==0) continue;
|
|
5371 |
if (TotalPixel<9999-1)
|
|
5372 |
{
|
|
5373 |
ptx[TotalPixel].X=j;
|
|
5374 |
ptx[TotalPixel].Y=i;
|
|
5375 |
score1[TotalPixel]=pixels[i*stride+j];
|
|
5376 |
used[TotalPixel]=0;
|
|
5377 |
used2[TotalPixel]=0;
|
|
5378 |
TotalPixel++;
|
|
5379 |
}
|
|
5380 |
}
|
|
5381 |
}
|
|
5382 |
//变幻;
|
|
5383 |
int minL=10;
|
|
5384 |
int totalfound=0;
|
|
5385 |
double ee=0.5;
|
|
5386 |
int first,second;
|
|
5387 |
for (first=0;first<TotalPixel-30;first++)
|
|
5388 |
{
|
|
5389 |
if (used[first]) continue;
|
|
5390 |
for (second=first+10;second<TotalPixel;second++)
|
|
5391 |
{
|
|
5392 |
if (used[second]) continue;
|
|
5393 |
if (used2[second]) continue;
|
|
5394 |
int counterk=0;
|
|
5395 |
int x1,y1,x2,y2;
|
|
5396 |
x1=ptx[first].X;y1=ptx[first].Y;
|
|
5397 |
x2=ptx[second].X;y2=ptx[second].Y;
|
|
5398 |
//判断距离,如果距离小于minL,放弃
|
|
5399 |
int dx,dy,dl;
|
|
5400 |
dx=x2-x1;dy=y2-y1;
|
|
5401 |
dl=(dx)*dx+dy*dy;
|
|
5402 |
if (dl<minL*minL) continue;
|
|
5403 |
double theta,ro;
|
|
5404 |
if (y2==y1) {theta=Pi/2;}
|
|
5405 |
else {theta=atan((double)x2-x1/y2-y1);}
|
|
5406 |
ro=((x1-centerX)*cos(theta)+(y1-centerY)*sin(theta))+max_length/2;
|
|
5407 |
for (int k=first+1;k<TotalPixel;k++)
|
|
5408 |
{
|
|
5409 |
if (used[k]) continue;
|
|
5410 |
int x3,y3;
|
|
5411 |
double ro3;
|
|
5412 |
x3=ptx[k].X;y3=ptx[k].Y;
|
|
5413 |
ro3=((x3-centerX)*cos(theta)+(y3-centerY)*sin(theta)+max_length/2);
|
|
5414 |
if (fabs(ro-ro3)<ee)
|
|
5415 |
{
|
|
5416 |
used2[k]=1;
|
|
5417 |
counterk++;
|
|
5418 |
}
|
|
5419 |
}
|
|
5420 |
if (counterk>Threshold)
|
|
5421 |
{
|
|
5422 |
for (int l=0;l<TotalPixel;l++)
|
|
5423 |
{
|
|
5424 |
if (used2[l]) used[l]=used2[l];
|
|
5425 |
}
|
|
5426 |
if (totalfound<1000-1)
|
|
5427 |
{
|
|
5428 |
res[totalfound].Pt=PointD(theta,ro-max_length/2);
|
|
5429 |
res[totalfound].Score=counterk;
|
|
5430 |
totalfound++;
|
|
5431 |
if (totalfound>=MaxFound) break;
|
|
5432 |
}
|
|
5433 |
break;
|
|
5434 |
}
|
|
5435 |
}
|
|
5436 |
}
|
|
5437 |
return totalfound;
|
|
5438 |
return 0;
|
|
5439 |
}
|
|
5440 |
int TransRGBToBayerGR(Gdiplus::Bitmap * bitmap1,CString sFilePathname)
|
|
5441 |
{
|
|
5442 |
if (bitmap1==NULL) {return 0;}
|
|
5443 |
int w,h;
|
|
5444 |
w=bitmap1->GetWidth();
|
|
5445 |
h=bitmap1->GetHeight();
|
|
5446 |
if (0==w||0==h) {return 0;}
|
|
5447 |
|
|
5448 |
Gdiplus::BitmapData bitmapdata0;
|
|
5449 |
UINT * pixels;
|
|
5450 |
Gdiplus::Rect rect0(0,0,w,h);
|
|
5451 |
|
|
5452 |
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapdata0);
|
|
5453 |
if (GdipStatus!=Gdiplus::Ok)
|
|
5454 |
{
|
|
5455 |
CString Errs1;
|
|
5456 |
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
|
5457 |
return 0;
|
|
5458 |
}
|
|
5459 |
pixels=(UINT *)bitmapdata0.Scan0 ;
|
|
5460 |
int stride=bitmapdata0.Stride/4;
|
|
5461 |
int stride2=(stride+63)&(-64);
|
|
5462 |
unsigned char * buf1=new unsigned char [h*stride2];
|
|
5463 |
//#pragma omp parallel for
|
|
5464 |
for (int i=0;i<h;i+=2)
|
|
5465 |
{
|
|
5466 |
COLOR c1;
|
|
5467 |
for (int j=0;j<w;j+=2)
|
|
5468 |
{
|
|
5469 |
c1.argb=pixels[i*stride+j];
|
|
5470 |
buf1[i*stride2+j]=c1.G;
|
|
5471 |
c1.argb=pixels[i*stride+j+1];
|
|
5472 |
buf1[i*stride2+j+1]=c1.R;
|
|
5473 |
}
|
|
5474 |
for (int j=0;j<w;j+=2)
|
|
5475 |
{
|
|
5476 |
c1.argb=pixels[(i+1)*stride+j];
|
|
5477 |
buf1[(i+1)*stride2+j]=c1.B;
|
|
5478 |
c1.argb=pixels[(i+1)*stride+j+1];
|
|
5479 |
buf1[(i+1)*stride2+j+1]=c1.G;
|
|
5480 |
}
|
|
5481 |
}
|
|
5482 |
bitmap1->UnlockBits(&bitmapdata0);
|
|
5483 |
SaveBufferToBmpFile(buf1,w,h,stride2,sFilePathname);
|
|
5484 |
delete []buf1;
|
|
5485 |
return true;
|
|
5486 |
}
|
|
5487 |
int TransRGBToBayerGR2(Gdiplus::Bitmap * bitmap1,CString sFilePathname)
|
|
5488 |
{
|
|
5489 |
if (bitmap1==NULL) {return 0;}
|
|
5490 |
int w,h;
|
|
5491 |
w=bitmap1->GetWidth();
|
|
5492 |
h=bitmap1->GetHeight();
|
|
5493 |
if (0==w||0==h) {return 0;}
|
|
5494 |
|
|
5495 |
Gdiplus::BitmapData bitmapdata0;
|
|
5496 |
UINT * pixels;
|
|
5497 |
Gdiplus::Rect rect0(0,0,w,h);
|
|
5498 |
|
|
5499 |
Gdiplus::Status GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapdata0);
|
|
5500 |
if (GdipStatus!=Gdiplus::Ok)
|
|
5501 |
{
|
|
5502 |
CString Errs1;
|
|
5503 |
Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
|
|
5504 |
return 0;
|
|
5505 |
}
|
|
5506 |
pixels=(UINT *)bitmapdata0.Scan0 ;
|
|
5507 |
int stride=bitmapdata0.Stride/4;
|
|
5508 |
unsigned char * buf1=new unsigned char [h*stride];
|
|
5509 |
#pragma omp parallel for
|
|
5510 |
for (int i=0;i<h;i+=2)
|
|
5511 |
{
|
|
5512 |
COLOR c1;
|
|
5513 |
for (int j=0;j<w;j+=2)
|
|
5514 |
{
|
|
5515 |
c1.argb=pixels[i*stride+j];
|
|
5516 |
buf1[(i/2)*stride+j/2]=c1.G;
|
|
5517 |
c1.argb=pixels[i*stride+j+1];
|
|
5518 |
buf1[(i/2)*stride+j/2+w/2]=c1.R;
|
|
5519 |
}
|
|
5520 |
for (int j=0;j<w;j+=2)
|
|
5521 |
{
|
|
5522 |
c1.argb=pixels[(i+1)*stride+j];
|
|
5523 |
buf1[(i/2+h/2)*stride+j/2]=c1.B;
|
|
5524 |
c1.argb=pixels[(i+1)*stride+j+1];
|
|
5525 |
buf1[(i/2+h/2)*stride+j/2+w/2]=c1.G;
|
|
5526 |
}
|
|
5527 |
}
|
|
5528 |
bitmap1->UnlockBits(&bitmapdata0);
|
|
5529 |
SaveBufferToBmpFile(buf1,w,h,stride,sFilePathname);
|
|
5530 |
delete [] buf1;
|
|
5531 |
return true;
|
|
5532 |
}
|
|
5533 |
|
|
5534 |
double RefCompare(double * buf1, int count1, double * buf2, int count2 ,int mode)
|
|
5535 |
{
|
|
5536 |
double refcount=0;
|
|
5537 |
int count=min(count1,count2);
|
|
5538 |
double a,b,c=0;
|
|
5539 |
for (int i=0;i<count;i++)
|
|
5540 |
{
|
|
5541 |
a=buf1[i];
|
|
5542 |
b=buf2[i];
|
|
5543 |
c+=(a-b)*(a-b);
|
|
5544 |
}
|
|
5545 |
refcount=sqrt(c);
|
|
5546 |
|
|
5547 |
return refcount;
|
|
5548 |
}
|
|
5549 |
/*
|
|
5550 |
#include "opencv2/opencv.hpp"
|
|
5551 |
#ifdef _DEBUG
|
|
5552 |
#pragma comment(lib,"opencv_core341d.lib")
|
|
5553 |
#pragma comment(lib,"opencv_imgproc341d.lib")
|
|
5554 |
#pragma comment(lib,"opencv_imgcodecs341d.lib")
|
|
5555 |
#pragma comment(lib,"opencv_highgui341d.lib")
|
|
5556 |
#else
|
|
5557 |
#pragma comment(lib,"opencv_core341.lib")
|
|
5558 |
#pragma comment(lib,"opencv_imgproc341.lib")
|
|
5559 |
#pragma comment(lib,"opencv_imgcodecs341.lib")
|
|
5560 |
#pragma comment(lib,"opencv_highgui341.lib")
|
|
5561 |
#endif
|
|
5562 |
*/
|
|
5563 |
#ifdef _WIN64
|
|
5564 |
|
|
5565 |
#include "E:\OpenCV3\opencv\build\include\opencv2\opencv.hpp"
|
|
5566 |
#ifdef _DEBUG
|
|
5567 |
#pragma comment(lib,"opencv_world310d.lib")
|
|
5568 |
#else
|
|
5569 |
#pragma comment(lib,"opencv_world310.lib")
|
|
5570 |
#endif
|
|
5571 |
int fdf1(double * pData, int width, int height, DftFilterPos filterPos[], int filterPosCount, int showstatus)
|
|
5572 |
{
|
|
5573 |
CString s1;
|
|
5574 |
double time1,time2;
|
|
5575 |
time1 = GetTickCountmS();
|
|
5576 |
|
|
5577 |
cv::Mat input(height,width,CV_64FC1,pData);
|
|
5578 |
|
|
5579 |
int w=cv::getOptimalDFTSize(input.cols);
|
|
5580 |
int h=cv::getOptimalDFTSize(input.rows);//获取最佳尺寸,快速傅立叶变换要求尺寸为2的n次方
|
|
5581 |
cv::Mat padded;
|
|
5582 |
cv::copyMakeBorder(input,padded,0,h-input.rows,0,w-input.cols,cv::BORDER_CONSTANT,cv::Scalar::all(0));//填充图像保存到padded中
|
|
5583 |
|
|
5584 |
cv::Mat plane[]={cv::Mat_<float>(padded),cv::Mat::zeros(padded.size(),CV_32F)};//创建通道
|
|
5585 |
cv::Mat complexIm1;
|
|
5586 |
cv::Mat complexIm2;
|
|
5587 |
cv::Mat complexIm3;
|
|
5588 |
|
|
5589 |
time2=GetTickCountmS();
|
|
5590 |
s1.Format(_T("fdf init %.3fmS\r\n"),time2-time1);
|
|
5591 |
TRACE(s1);
|
|
5592 |
|
|
5593 |
if (showstatus)
|
|
5594 |
{
|
|
5595 |
cv::Mat T;
|
|
5596 |
plane[0].copyTo(T);
|
|
5597 |
cv::normalize(T,T,255,0,CV_MINMAX);
|
|
5598 |
cv::imwrite("D:\\1\\fdf_padded.bmp",cv::Mat_<uchar>(T));
|
|
5599 |
}
|
|
5600 |
|
|
5601 |
time1 = GetTickCountmS();
|
|
5602 |
//*******************************dft************************************
|
|
5603 |
cv::merge(plane,2,complexIm1);//合并通道
|
|
5604 |
cv::dft(complexIm1,complexIm2);//进行傅立叶变换,结果保存在自身
|
|
5605 |
cv::split(complexIm2,plane);//分离通道
|
|
5606 |
|
|
5607 |
time2=GetTickCountmS();
|
|
5608 |
s1.Format(_T("fdf dft %.3fmS\r\n"),time2-time1);
|
|
5609 |
TRACE(s1);
|
|
5610 |
|
|
5611 |
if (1)
|
|
5612 |
{
|
|
5613 |
time1 = GetTickCountmS();
|
|
5614 |
//*******************************shift************************************
|
|
5615 |
{
|
|
5616 |
int cx=plane[0].cols/2;
|
|
5617 |
int cy=plane[0].rows/2;
|
|
5618 |
cv::Mat temp;
|
|
5619 |
cv::Mat part1(plane[0],cv::Rect(0,0,cx,cy));
|
|
5620 |
cv::Mat part2(plane[0],cv::Rect(cx,0,cx,cy));
|
|
5621 |
cv::Mat part3(plane[0],cv::Rect(0,cy,cx,cy));
|
|
5622 |
cv::Mat part4(plane[0],cv::Rect(cx,cy,cx,cy));
|
|
5623 |
|
|
5624 |
part1.copyTo(temp);
|
|
5625 |
part4.copyTo(part1);
|
|
5626 |
temp.copyTo(part4);
|
|
5627 |
|
|
5628 |
part2.copyTo(temp);
|
|
5629 |
part3.copyTo(part2);
|
|
5630 |
temp.copyTo(part3);
|
|
5631 |
}
|
|
5632 |
{
|
|
5633 |
int cx=plane[0].cols/2;
|
|
5634 |
int cy=plane[0].rows/2;
|
|
5635 |
cv::Mat temp;
|
|
5636 |
|
|
5637 |
cv::Mat part1(plane[1],cv::Rect(0,0,cx,cy));
|
|
5638 |
cv::Mat part2(plane[1],cv::Rect(cx,0,cx,cy));
|
|
5639 |
cv::Mat part3(plane[1],cv::Rect(0,cy,cx,cy));
|
|
5640 |
cv::Mat part4(plane[1],cv::Rect(cx,cy,cx,cy));
|
|
5641 |
|
|
5642 |
part1.copyTo(temp);
|
|
5643 |
part4.copyTo(part1);
|
|
5644 |
temp.copyTo(part4);
|
|
5645 |
|
|
5646 |
part2.copyTo(temp);
|
|
5647 |
part3.copyTo(part2);
|
|
5648 |
temp.copyTo(part3);
|
|
5649 |
}
|
|
5650 |
time2=GetTickCountmS();
|
|
5651 |
s1.Format(_T("fdf shift %.3fmS\r\n"),time2-time1);
|
|
5652 |
TRACE(s1);
|
|
5653 |
}
|
|
5654 |
|
|
5655 |
if (showstatus)
|
|
5656 |
{
|
|
5657 |
cv::Mat T;
|
|
5658 |
cv::magnitude(plane[0],plane[1],T);
|
|
5659 |
T+=cv::Scalar::all(1);
|
|
5660 |
cv::log(T,T);
|
|
5661 |
cv::normalize(T,T,255,0,CV_MINMAX);
|
|
5662 |
cv::imwrite("D:\\1\\fdf_dft.bmp",cv::Mat_<uchar>(T));
|
|
5663 |
}
|
|
5664 |
|
|
5665 |
if (1)
|
|
5666 |
{
|
|
5667 |
time1 = GetTickCountmS();
|
|
5668 |
//*******************************filter************************************
|
|
5669 |
for (int k=0; k<filterPosCount; k++)
|
|
5670 |
{
|
|
5671 |
int startx = w/2 - filterPos[k].x - filterPos[k].w/2;
|
|
5672 |
int endx = w/2 - filterPos[k].x + filterPos[k].w/2;
|
|
5673 |
int starty = h/2 - filterPos[k].y - filterPos[k].h/2;
|
|
5674 |
int endy = h/2 - filterPos[k].y + filterPos[k].h/2;
|
|
5675 |
|
|
5676 |
if (startx<0) startx = 0;
|
|
5677 |
if (starty<0) starty = 0;
|
|
5678 |
if (endx>w) endx = w;
|
|
5679 |
if (endy>h) endy = h;
|
|
5680 |
|
|
5681 |
for (int i=starty; i<endy; ++i)
|
|
5682 |
{
|
|
5683 |
float*p0=plane[0].ptr<float>(i);
|
|
5684 |
for (int j=startx; j<endx; j++)
|
|
5685 |
{
|
|
5686 |
p0[j]=0;
|
|
5687 |
}
|
|
5688 |
|
|
5689 |
float*p1=plane[1].ptr<float>(i);
|
|
5690 |
for (int j=startx; j<endx; j++)
|
|
5691 |
{
|
|
5692 |
p1[j]=0;
|
|
5693 |
}
|
|
5694 |
}
|
|
5695 |
}
|
|
5696 |
|
|
5697 |
time2=GetTickCountmS();
|
|
5698 |
s1.Format(_T("fdf filter %.3fmS\r\n"),time2-time1);
|
|
5699 |
TRACE(s1);
|
|
5700 |
}
|
|
5701 |
|
|
5702 |
if (showstatus)
|
|
5703 |
{
|
|
5704 |
cv::Mat T;
|
|
5705 |
cv::magnitude(plane[0],plane[1],T);
|
|
5706 |
T+=cv::Scalar::all(1);
|
|
5707 |
cv::log(T,T);
|
|
5708 |
cv::normalize(T,T,255,0,CV_MINMAX);
|
|
5709 |
cv::imwrite("D:\\1\\fdf_dft_filtered.bmp",cv::Mat_<uchar>(T));
|
|
5710 |
}
|
|
5711 |
|
|
5712 |
if (1)
|
|
5713 |
{
|
|
5714 |
time1 = GetTickCountmS();
|
|
5715 |
//*******************************shift************************************
|
|
5716 |
{
|
|
5717 |
int cx=plane[0].cols/2;
|
|
5718 |
int cy=plane[0].rows/2;
|
|
5719 |
cv::Mat temp;
|
|
5720 |
cv::Mat part1(plane[0],cv::Rect(0,0,cx,cy));
|
|
5721 |
cv::Mat part2(plane[0],cv::Rect(cx,0,cx,cy));
|
|
5722 |
cv::Mat part3(plane[0],cv::Rect(0,cy,cx,cy));
|
|
5723 |
cv::Mat part4(plane[0],cv::Rect(cx,cy,cx,cy));
|
|
5724 |
|
|
5725 |
part1.copyTo(temp);
|
|
5726 |
part4.copyTo(part1);
|
|
5727 |
temp.copyTo(part4);
|
|
5728 |
|
|
5729 |
part2.copyTo(temp);
|
|
5730 |
part3.copyTo(part2);
|
|
5731 |
temp.copyTo(part3);
|
|
5732 |
}
|
|
5733 |
{
|
|
5734 |
int cx=plane[0].cols/2;
|
|
5735 |
int cy=plane[0].rows/2;
|
|
5736 |
cv::Mat temp;
|
|
5737 |
|
|
5738 |
cv::Mat part1(plane[1],cv::Rect(0,0,cx,cy));
|
|
5739 |
cv::Mat part2(plane[1],cv::Rect(cx,0,cx,cy));
|
|
5740 |
cv::Mat part3(plane[1],cv::Rect(0,cy,cx,cy));
|
|
5741 |
cv::Mat part4(plane[1],cv::Rect(cx,cy,cx,cy));
|
|
5742 |
|
|
5743 |
part1.copyTo(temp);
|
|
5744 |
part4.copyTo(part1);
|
|
5745 |
temp.copyTo(part4);
|
|
5746 |
|
|
5747 |
part2.copyTo(temp);
|
|
5748 |
part3.copyTo(part2);
|
|
5749 |
temp.copyTo(part3);
|
|
5750 |
}
|
|
5751 |
|
|
5752 |
time2=GetTickCountmS();
|
|
5753 |
s1.Format(_T("fdf ishift %.3fmS\r\n"),time2-time1);
|
|
5754 |
TRACE(s1);
|
|
5755 |
}
|
|
5756 |
|
|
5757 |
time1 = GetTickCountmS();
|
|
5758 |
//*****************************idft**************************************
|
|
5759 |
cv::merge(plane,2,complexIm2);
|
|
5760 |
cv::idft(complexIm2,complexIm3);//傅立叶逆变换
|
|
5761 |
cv::split(complexIm3,plane);//结果也是复数
|
|
5762 |
|
|
5763 |
time2=GetTickCountmS();
|
|
5764 |
s1.Format(_T("fdf idft %.3fmS\r\n"),time2-time1);
|
|
5765 |
TRACE(s1);
|
|
5766 |
|
|
5767 |
time1 = GetTickCountmS();
|
|
5768 |
cv::Mat output;
|
|
5769 |
plane[0].copyTo(output);
|
|
5770 |
cv::normalize(output,output,255,0,CV_MINMAX);
|
|
5771 |
for (int i=0; i<height; ++i)
|
|
5772 |
{
|
|
5773 |
float*p0=output.ptr<float>(i);
|
|
5774 |
for (int j=0; j<width; ++j)
|
|
5775 |
{
|
|
5776 |
pData[i*width+j] = p0[j];
|
|
5777 |
}
|
|
5778 |
}
|
|
5779 |
time2=GetTickCountmS();
|
|
5780 |
s1.Format(_T("fdf output %.3fmS\r\n"),time2-time1);
|
|
5781 |
TRACE(s1);
|
|
5782 |
|
|
5783 |
if (showstatus)
|
|
5784 |
{
|
|
5785 |
cv::Mat T;
|
|
5786 |
plane[0].copyTo(T);
|
|
5787 |
cv::normalize(T,T,255,0,CV_MINMAX);
|
|
5788 |
cv::imwrite("D:\\1\\fdf_idft.bmp",cv::Mat_<uchar>(T));
|
|
5789 |
}
|
|
5790 |
|
|
5791 |
return 0;
|
|
5792 |
}
|
|
5793 |
#endif /* _WIN64 */
|
|
5794 |
|