/* The transmission estimation algorithm is in here. The detailed description of the algorithm is presented in "http://mcl.korea.ac.kr/projects/dehazing". See also J.-H. Kim, W.-D. Jang, Y. Park, D.-H. Lee, J.-Y. Sim, C.-S. Kim, "Temporally coherent real-time video dehazing," in Proc. IEEE ICIP, 2012. The transmission is estimated by maximizing the contrast of restored image while minimizing the information loss, which denotes the trucated pixel value. The transmission estimation is block based approach, and thus its performance depends on the size of block. Last updated: 2013-02-07 Author: Jin-Hwan, Kim. */ #include "dehazing.h" /* Function: TransmissionEstimation Description: Estiamte the transmission in the frame(Color) Specified size. Parameters: nFrame - frame no. nWid - frame width nHei - frame height. Return: m_pfTransmission */ void dehazing::TransmissionEstimationColor(int *pnImageR, int *pnImageG, int *pnImageB, float *pfTransmission,int *pnImageRP, int *pnImageGP, int *pnImageBP, float *pfTransmissionP,int nFrame, int nWid, int nHei) { int nX, nY, nXstep, nYstep; float fTrans; if(m_bPreviousFlag == true&&nFrame>0) { for(nY=0; nY0) { for(nY=0; nY>7; // (I-A)/t + A --> ((I-A)*k*128 + A*128)/128 nSquaredOut = nOut * nOut; if(nOut>255) { nSumofSLoss += (nOut - 255)*(nOut - 255); nLossCount++; } else if(nOut < 0) { nSumofSLoss += nSquaredOut; nLossCount++; } nSumofSquaredOuts += nSquaredOut; nSumofOuts += nOut; } } fMean = (float)(nSumofOuts)/(float)(nNumberofPixels); fCost = m_fLambda1 * (float)nSumofSLoss/(float)(nNumberofPixels) - ((float)nSumofSquaredOuts/(float)nNumberofPixels - fMean*fMean); if(nCounter==0 || fMinCost > fCost) { fMinCost = fCost; fOptTrs = fTrans; } fTrans += 0.1f; nTrans = (int)(1.0f/fTrans*128.0f); } return fOptTrs; } /* Function: NFTrsEstimation Description: Estiamte the transmission in the block. (COLOR) The algorithm use exhaustive searching method and its step size is sampled to 0.1 Parameters: nStartx - top left point of a block nStarty - top left point of a block nWid - frame width nHei - frame height. Return: fOptTrs */ float dehazing::NFTrsEstimationColor(int *pnImageR, int *pnImageG, int *pnImageB, int nStartX, int nStartY, int nWid, int nHei) { int nCounter; int nX, nY; int nEndX; int nEndY; int nOutR, nOutG, nOutB; int nSquaredOut; int nSumofOuts; int nSumofSquaredOuts; float fTrans, fOptTrs; int nTrans; int nSumofSLoss; float fCost, fMinCost, fMean; int nNumberofPixels, nLossCount; nEndX = min(nStartX+m_nTBlockSize, nWid); nEndY = min(nStartY+m_nTBlockSize, nHei); nNumberofPixels = (nEndY-nStartY)*(nEndX-nStartX) * 3; fTrans = 0.3f; nTrans = 427; for(nCounter=0; nCounter<7; nCounter++) { nSumofSLoss = 0; nLossCount = 0; nSumofSquaredOuts = 0; nSumofOuts = 0; for(nY=nStartY; nY>7; // (I-A)/t + A --> ((I-A)*k*128 + A*128)/128 nOutG = ((pnImageG[nY*nWid+nX] - m_anAirlight[1])*nTrans + 128*m_anAirlight[1])>>7; nOutR = ((pnImageR[nY*nWid+nX] - m_anAirlight[2])*nTrans + 128*m_anAirlight[2])>>7; if(nOutR>255) { nSumofSLoss += (nOutR - 255)*(nOutR - 255); nLossCount++; } else if(nOutR < 0) { nSumofSLoss += nOutR * nOutR; nLossCount++; } if(nOutG>255) { nSumofSLoss += (nOutG - 255)*(nOutG - 255); nLossCount++; } else if(nOutG < 0) { nSumofSLoss += nOutG * nOutG; nLossCount++; } if(nOutB>255) { nSumofSLoss += (nOutB - 255)*(nOutB - 255); nLossCount++; } else if(nOutB < 0) { nSumofSLoss += nOutB * nOutB; nLossCount++; } nSumofSquaredOuts += nOutB * nOutB + nOutR * nOutR + nOutG * nOutG;; nSumofOuts += nOutR + nOutG + nOutB; } } fMean = (float)(nSumofOuts)/(float)(nNumberofPixels); fCost = m_fLambda1 * (float)nSumofSLoss/(float)(nNumberofPixels) - ((float)nSumofSquaredOuts/(float)nNumberofPixels - fMean*fMean); if(nCounter==0 || fMinCost > fCost) { fMinCost = fCost; fOptTrs = fTrans; } fTrans += 0.1f; nTrans = (int)(1.0f/fTrans*128.0f); } return fOptTrs; } /* Function: NFTrsEstimationP Description: Estiamte the transmission in the block. The algorithm use exhaustive searching method and its step size is sampled to 0.1. The previous frame information is used to estimate transmission. Parameters: nStartx - top left point of a block nStarty - top left point of a block nWid - frame width nHei - frame height. Return: fOptTrs */ float dehazing::NFTrsEstimationP(int *pnImageY, int *pnImageYP, float *pfTransmissionP, int nStartX, int nStartY, int nWid, int nHei) { int nCounter; // for find out transmission 0.1~1.0, 10 iteration int nX, nY; // variable for index int nEndX; int nEndY; float fMean; int nOut; float fPreTrs; int nSquaredOut; int nSumofOuts; int nSumofSquaredOuts; int nTrans; int nSumofSLoss; float fCost, fMinCost, fTrans, fOptTrs; int nNumberofPixels; nEndX = min(nStartX+m_nTBlockSize, nWid); nEndY = min(nStartY+m_nTBlockSize, nHei); nNumberofPixels = (nEndY-nStartY)*(nEndX-nStartX); fTrans = 0.3f; // initial transmission value nTrans = 427; fPreTrs = 0; float fNewKSum = 0; // Sum of new kappa which is multiplied the weight float fNewK; // New kappa float fWi; // Weight float fPreJ; // evade 0 division float fWsum = 0; // Sum of weight int nIdx = 0; int nLossCount; for(nY=nStartY; nY>7; // (I-A)/t + A --> ((I-A)*k*128 + A*128)/128 nSquaredOut = nOut * nOut; if(nOut>255) { nSumofSLoss += (nOut - 255)*(nOut - 255); nLossCount++; } else if(nOut < 0) { nSumofSLoss += nSquaredOut; nLossCount++; } nSumofSquaredOuts += nSquaredOut; nSumofOuts += nOut; } } fMean = (float)(nSumofOuts)/(float)(nNumberofPixels); fCost = m_fLambda1 * (float)nSumofSLoss/(float)(nNumberofPixels) // information loss cost - ((float)nSumofSquaredOuts/(float)nNumberofPixels - fMean*fMean) // contrast cost + m_fLambda2/fPreTrs/fPreTrs*fWsum/(float)nNumberofPixels*((fPreTrs-fTrans)*(fPreTrs-fTrans)*255.0f*255.0f);// fPreTrs/fPreTrs*fWsum/(float)nNumberofPixels if(nCounter==0 || fMinCost > fCost) { fMinCost = fCost; fOptTrs = fTrans; } fTrans += 0.1f; nTrans = (int)(1/fTrans*128.0f); } return fOptTrs; } /* Function: NFTrsEstimationP(COLOR) Description: Estiamte the transmission in the block. The algorithm use exhaustive searching method and its step size is sampled to 0.1. The previous frame information is used to estimate transmission. Parameters: nStartx - top left point of a block nStarty - top left point of a block nWid - frame width nHei - frame height. Return: fOptTrs */ float dehazing::NFTrsEstimationPColor(int *pnImageR, int *pnImageG, int *pnImageB, int *pnImageRP, int *pnImageGP, int *pnImageBP, float *pfTransmissionP, int nStartX, int nStartY, int nWid, int nHei) { int nCounter; int nX, nY; int nEndX; int nEndY; float fMean; int nOutR, nOutG, nOutB; float fPreTrs; int nSquaredOut; int nSumofOuts; int nSumofSquaredOuts; int nTrans; int nSumofSLoss; float fCost, fMinCost, fTrans, fOptTrs; int nNumberofPixels; nEndX = min(nStartX+m_nTBlockSize, nWid); nEndY = min(nStartY+m_nTBlockSize, nHei); nNumberofPixels = (nEndY-nStartY)*(nEndX-nStartX) * 3; fTrans = 0.3f; nTrans = 427; fPreTrs = 0; float fNewKSum = 0; float fNewK; float fWiR, fWiG, fWiB; float fPreJR, fPreJG, fPreJB; float fWsum = 0; int nIdx = 0; int nLossCount; for(nY=nStartY; nY>7; nOutG = ((pnImageG[nY*nWid+nX] - m_anAirlight[1])*nTrans + 128*m_anAirlight[1])>>7; nOutR = ((pnImageR[nY*nWid+nX] - m_anAirlight[2])*nTrans + 128*m_anAirlight[2])>>7; // (I-A)/t + A --> ((I-A)*k*128 + A*128)/128 if(nOutR>255) { nSumofSLoss += (nOutR - 255)*(nOutR - 255); nLossCount++; } else if(nOutR < 0) { nSumofSLoss += nOutR * nOutR; nLossCount++; } if(nOutG>255) { nSumofSLoss += (nOutG - 255)*(nOutG - 255); nLossCount++; } else if(nOutG < 0) { nSumofSLoss += nOutG * nOutG; nLossCount++; } if(nOutB>255) { nSumofSLoss += (nOutB - 255)*(nOutB - 255); nLossCount++; } else if(nOutB < 0) { nSumofSLoss += nOutB * nOutB; nLossCount++; } nSumofSquaredOuts += nOutB * nOutB + nOutR * nOutR + nOutG * nOutG; nSumofOuts += nOutR + nOutG + nOutB; } } fMean = (float)(nSumofOuts)/(float)(nNumberofPixels); fCost = m_fLambda1 * (float)nSumofSLoss/(float)(nNumberofPixels) - ((float)nSumofSquaredOuts/(float)nNumberofPixels - fMean*fMean) + m_fLambda2/fPreTrs/fPreTrs*fWsum/(float)nNumberofPixels*((fPreTrs-fTrans)*(fPreTrs-fTrans)*255.0f*255.0f); if(nCounter==0 || fMinCost > fCost) { fMinCost = fCost; fOptTrs = fTrans; } fTrans += 0.1f; nTrans = (int)(1/fTrans*128.0f); } return fOptTrs; }