// GainMatrix.cpp: implementation of the CGainMatrix class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "GainMatrix.h" #include "String.Format.tlh" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif CGainMatrix* CGainMatrix::m_instance = NULL; #define FULL_IMG_WIDTH 3072L #define FULL_IMG_HEIGHT 2560L const int nGAINMIN = 65535; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CGainMatrix::CGainMatrix(int width, int height, int woffset, int hoffset, int refrencenum, WORD maxpv) :m_nHeight(height), m_nWidth(width), m_nHOffset(hoffset), m_nWOffset(woffset), m_nRefrenceNum(refrencenum), m_nMaxPV(maxpv) { int i = 0; m_wGainBuffer = new WORD * [m_nRefrenceNum]; memset(m_wGainBuffer, 0, m_nRefrenceNum * sizeof(WORD)); for (i = 0; i < m_nRefrenceNum; i++) { m_wGainBuffer[i] = NULL; } m_nAverage = new int[m_nRefrenceNum]; for (i = 0; i < m_nRefrenceNum; i++) { m_nAverage[i] = 0; } m_nRefrenceCount = 0; w_gOffset = 50; m_nAverageCts = 0; m_nCurRefIndex = -1; } CGainMatrix::~CGainMatrix() { if (m_wGainBuffer != NULL) { for (int i = 0; i < m_nRefrenceNum; i++) { if (m_wGainBuffer[i] != NULL) { delete[] m_wGainBuffer[i]; } } delete[] m_wGainBuffer; } m_wGainBuffer = NULL; if (m_nAverage) { delete[] m_nAverage; m_nAverage = NULL; } } CGainMatrix* CGainMatrix::Instance() { if (m_instance == NULL) { m_instance = new CGainMatrix(FULL_IMG_WIDTH, FULL_IMG_HEIGHT, 0, 0, 1, 16383); } return m_instance; } void CGainMatrix::ApplyGainMap(WORD* wImage) { // 改成3幅图: 分别是500,1000,1500; DWORD temp; int i, j, k, offset; for (i = 0; i < m_nRefrenceNum; i++) { if (m_wGainBuffer[i] == NULL) { return; } } for (offset = 0; offset < m_nWidth * m_nHOffset; offset++) { wImage[offset] = m_nMaxPV; } for (i = m_nHOffset; i < m_nHeight - m_nHOffset; i++) { offset = i * m_nWidth; for (j = 0; j < m_nWOffset; j++) { wImage[offset] = m_nMaxPV; offset++; } for (; j < m_nWidth - m_nWOffset; j++) { if (m_nRefrenceNum == 1) { if (*(m_wGainBuffer[0] + i * m_nWidth + j) == 0) { offset++; continue; } temp = *(wImage + i * m_nWidth + j) * m_nAverage[0] / (*(m_wGainBuffer[0] + i * m_nWidth + j)) + w_gOffset; } else { if (*(wImage + i * m_nWidth + j) < *(m_wGainBuffer[0] + i * m_nWidth + j)) { if (*(m_wGainBuffer[0] + i * m_nWidth + j) == 0) { offset++; continue; } temp = *(wImage + i * m_nWidth + j) * m_nAverage[0] / (*(m_wGainBuffer[0] + i * m_nWidth + j)) + w_gOffset; } else { for (k = 0; k < m_nRefrenceNum - 1; k++) { if (*(wImage + i * m_nWidth + j) >= *(m_wGainBuffer[k] + i * m_nWidth + j) && *(wImage + i * m_nWidth + j) < *(m_wGainBuffer[k + 1] + i * m_nWidth + j)) break; } if (k == m_nRefrenceNum - 1) k = max(0, (k - 1)); if ((k + 1) <= (m_nRefrenceNum - 1)) { if ((*(m_wGainBuffer[k + 1] + i * m_nWidth + j) - *(m_wGainBuffer[k] + i * m_nWidth + j)) == 0) { offset++; continue; } } temp = m_nAverage[k] + (*(wImage + i * m_nWidth + j) - *(m_wGainBuffer[k] + i * m_nWidth + j)) * (m_nAverage[k + 1] - m_nAverage[k]) / (*(m_wGainBuffer[k + 1] + i * m_nWidth + j) - *(m_wGainBuffer[k] + i * m_nWidth + j)) + w_gOffset; } } if (temp > m_nMaxPV) *(wImage + i * m_nWidth + j) = m_nMaxPV; else *(wImage + i * m_nWidth + j) = WORD(temp); offset++; } for (; j < m_nWidth; j++) { wImage[offset] = m_nMaxPV; offset++; } } for (offset = i * m_nWidth; offset < m_nWidth * m_nHeight; offset++) { wImage[offset] = m_nMaxPV; } } bool CGainMatrix::LoadGainMap(void) { if (m_nRefrenceCount >= m_nRefrenceNum) { return false; } if (m_wGainBuffer[m_nRefrenceCount] != NULL) { delete[] m_wGainBuffer[m_nRefrenceCount]; } m_wGainBuffer[m_nRefrenceCount] = new WORD[m_nHeight * m_nWidth]; if (m_wGainBuffer[m_nRefrenceCount] == NULL) { return false; } m_nRefrenceCount++; return true; } bool CGainMatrix::LoadGainMap(const char* filename) { if (m_nRefrenceCount >= m_nRefrenceNum) { return false; } if (m_wGainBuffer[m_nRefrenceCount] != NULL) { delete[] m_wGainBuffer[m_nRefrenceCount]; } m_wGainBuffer[m_nRefrenceCount] = new WORD[m_nHeight * m_nWidth]; if (m_wGainBuffer[m_nRefrenceCount] == NULL) return false; // Check if the file exist or not FILE* fp = fopen(filename, "rb"); if (!fp) { return false; } if (fread(m_wGainBuffer[m_nRefrenceCount], 1, (UINT)(m_nHeight * m_nWidth * sizeof(WORD)), fp) != (UINT)(m_nHeight * m_nWidth * sizeof(WORD))) { fclose(fp); return false; } fclose(fp); //calculate avg pv ULONGLONG dwSum = 0; DWORD dwIndex = 0; int i, j; DWORD dwCts = 0; for (i = m_nHOffset; i < m_nHeight - m_nHOffset; i += 8) { dwIndex = i * m_nWidth; for (j = m_nWOffset; j < m_nWidth - m_nWOffset; j += 8) { dwSum += *(m_wGainBuffer[m_nRefrenceCount] + dwIndex + j); dwCts++; } } m_nAverage[m_nRefrenceCount] = dwSum / dwCts; char szOut[128]; sprintf(szOut, "LoadGainMap m_nAverage[%i]=%i\n", m_nRefrenceCount, m_nAverage[m_nRefrenceCount]); OutputDebugStringA(szOut); m_nRefrenceCount++; if (m_nRefrenceCount == m_nRefrenceNum) { PlaceRefrenceInOrder(); } return true; } bool CGainMatrix::LoadGainMap(WORD* wImage) { if (m_nRefrenceCount >= m_nRefrenceNum) { return false; } if (wImage == NULL) { return false; } if (m_wGainBuffer[m_nRefrenceCount] == NULL) { m_wGainBuffer[m_nRefrenceCount] = new WORD[m_nHeight * m_nWidth]; } if (m_wGainBuffer[m_nRefrenceCount] == NULL) return false; // Check if the file exist or not memcpy(m_wGainBuffer[m_nRefrenceCount], wImage, (UINT)(m_nHeight * m_nWidth * sizeof(WORD))); //calculate avg pv LONGLONG dwSum = 0;//add by song 2014-9-27 64位类型,防止越界 DWORD dwIndex = 0; int i, j; DWORD dwCts = 0; for (i = m_nHOffset; i < m_nHeight - m_nHOffset; i += 8) { dwIndex = i * m_nWidth; for (j = m_nWOffset; j < m_nWidth - m_nWOffset; j += 8) { dwSum += *(m_wGainBuffer[m_nRefrenceCount] + dwIndex + j); dwCts++; } } m_nAverage[m_nRefrenceCount] = dwSum / dwCts; m_nRefrenceCount++; if (m_nRefrenceCount == m_nRefrenceNum) { PlaceRefrenceInOrder(); } return true; } void CGainMatrix::PlaceRefrenceInOrder() { WORD nMin = nGAINMIN; WORD nMin_Index = 0; WORD nTemp = 0; WORD* nTempPtr = NULL; int i, j; for (i = 0; i < m_nRefrenceNum; i++) { if (m_wGainBuffer[i] == NULL) { return; } } for (i = 0; i < m_nRefrenceNum; i++) { nMin = nGAINMIN; nMin_Index = 0; for (j = i; j < m_nRefrenceNum; j++) { if (m_nAverage[j] <= nMin) { nMin = m_nAverage[j]; nMin_Index = j; } } nTemp = m_nAverage[i]; m_nAverage[i] = m_nAverage[nMin_Index]; m_nAverage[nMin_Index] = nTemp; nTempPtr = m_wGainBuffer[i]; m_wGainBuffer[i] = m_wGainBuffer[nMin_Index]; m_wGainBuffer[nMin_Index] = nTempPtr; } } bool CGainMatrix::AverageGainMap(WORD* wImage, int nRefIndex) { int dwCts = m_nWidth * m_nHeight; if (NULL == m_wGainBuffer[nRefIndex]) { return false; } if (m_nCurRefIndex != nRefIndex) { m_nCurRefIndex = nRefIndex; m_nAverageCts = 0; memcpy(m_wGainBuffer[nRefIndex], wImage, dwCts * sizeof(WORD)); m_nAverageCts++; } else { for (int i = 0; i < dwCts; i++) { m_wGainBuffer[nRefIndex][i] = WORD(float(m_wGainBuffer[nRefIndex][i]) * m_nAverageCts / (m_nAverageCts + 1) + float(wImage[i]) / (m_nAverageCts + 1)); } m_nAverageCts++; } return true; } bool CGainMatrix::AverageGainMap(WORD* wImage, int refenceindex, bool bStart) { int dwCts = m_nWidth * m_nHeight; if (m_wGainBuffer[refenceindex] == NULL) return false; if (bStart) { m_nAverageCts = 0; memcpy(m_wGainBuffer[refenceindex], wImage, dwCts * sizeof(WORD)); m_nAverageCts++; return true; } else { //average offset for (int i = 0; i < dwCts; i++) { m_wGainBuffer[refenceindex][i] = WORD(float(m_wGainBuffer[refenceindex][i]) * m_nAverageCts / (m_nAverageCts + 1) + float(wImage[i]) / (m_nAverageCts + 1)); } m_nAverageCts++; return true; } return true; } bool CGainMatrix::StoreGainMap(const char* filename, int refenceindex) { if (refenceindex > m_nRefrenceNum) return false; if (m_wGainBuffer[refenceindex] == NULL) { return false; } //do it at here //calculate avg pv ULONGLONG dwSum = 0; DWORD dwIndex = 0; int i, j; DWORD dwCts = 0; for (i = m_nHOffset; i < m_nHeight - m_nHOffset; i += 8) { dwIndex = i * m_nWidth; for (j = m_nWOffset; j < m_nWidth - m_nWOffset; j += 8) { dwSum += *(m_wGainBuffer[refenceindex] + dwIndex + j); dwCts++; } } m_nAverage[refenceindex] = dwSum / dwCts; dwSum = 0; dwIndex = 0; i = 0; j = 0; dwCts = 0; for (i = 0; i < m_nHeight; i += 8) { dwIndex = i * m_nWidth; for (j = 0; j < m_nWidth; j += 8) { dwSum += *(m_wGainBuffer[refenceindex] + dwIndex + j); dwCts++; } } int nAverage = dwSum / dwCts; try { FILE* fp; fp = fopen(filename, "wb"); if (fwrite(m_wGainBuffer[refenceindex], 1, m_nHeight * m_nWidth * sizeof(WORD), fp) != m_nHeight * m_nWidth * sizeof(WORD)) { ASSERT("123456"); } fclose(fp); } catch (...) { return false; } return true; }