// PixMatrix.cpp: implementation of the CPixMatrix class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "PixMatrix.h" #include "memory.h" #include "math.h" #include "String.Format.tlh" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #define FULL_IMG_WIDTH 4000L #define FULL_IMG_HEIGHT 4000L #define PIXEL_MAX_VALUE 65536 CPixMatrix* CPixMatrix::m_instance = NULL; CPixMatrix* CPixMatrix::Instance() { if(m_instance == NULL) { m_instance = new CPixMatrix(FULL_IMG_WIDTH, FULL_IMG_HEIGHT, 15, 45); } return m_instance; } CPixMatrix::CPixMatrix(int width, int height, int woffset, int hoffset, int nPixelMax) :m_nWidth(width), m_nHeight(height), m_nWOffset(woffset), m_nHOffset(hoffset), m_nPixelMax(nPixelMax) { m_BadPixelMap = NULL; m_BadNewPixelMap = NULL; m_BadPixArray = NULL; m_xLineMap = NULL; m_yLineMap = NULL; m_doubleLineMap = NULL; m_NewMap = new PIX_MAP[m_nHeight]; //m_curImg = NULL;////////////////////////chenGN 2013.01.31 //m_lastImg = NULL;////////////////////////chenGN 2013.01.31 m_mapImg = NULL; m_curAvg = -1; m_lastAvg = -1; ZeroMemory(m_charFilename, 256); m_TempImage = new unsigned short [ m_nWidth * m_nHeight ]; m_TempImage1 = new unsigned short [ m_nWidth * m_nHeight ]; //nWidth = 0; //nHeight = 0; m_pBadPixNum = NULL; //m_datalen = new int [ 400 ]; m_nLinePoint = 50;////×?D??μ??μ?êy, zhaoyiru, 2017.05.09 m_nLineData = int( (MAXI_BADPIX_COUNT - MAX_PIX_MAP_LINE) / m_nLinePoint);//×?′ó?μ????êy, zhaoyiru, 2017.05.09 m_datalen = new int[ m_nLineData ] ; memset(m_datalen, -1, sizeof(int)* m_nLineData ); } CPixMatrix::~CPixMatrix() { if(m_NewMap) { delete [] m_NewMap; m_NewMap = NULL; } if(m_BadPixArray) { delete [] m_BadPixArray; m_BadPixArray = NULL; } if( m_TempImage != NULL ) { delete [] m_TempImage; m_TempImage = NULL; } if( m_TempImage1 != NULL ) { delete [] m_TempImage1; m_TempImage1 = NULL; } if (m_mapImg)//add by ys20180109不在析构函数中释放的话会造成内存泄漏 { delete[] m_mapImg; m_mapImg = NULL; }//add end FreeBadPixelMap(); //FreeBadNewPixelMap(); FreeDBadLineMap(); if( m_pBadPixNum != NULL ) { //delete m_pBadPixNum; m_pBadPixNum = NULL; } if( m_datalen != NULL ) { delete [] m_datalen; m_datalen = NULL; } } void CPixMatrix::CorrectBadPixels(WORD* image) { long line; long pix_num; long bad_pix_num; long bad_num; long *p_bad_pix_num; float new_value; long w_new_value; float divisor; WORD *p_line, *p_prev_line, *p_next_line; long unProcLineNum; long unProcTotalNum = 0; if(m_BadPixelMap == NULL){ // can't do anything without a map return; } if(m_BadPixArray == NULL) { m_BadPixArray = new long [MAXI_BADPIX_COUNT*sizeof(long)]; if(m_BadPixArray == NULL) { return; } } MarkBadAdjacentPixels(); for(line = 0 ; line < m_nHeight ; ++line) { m_NewMap[line].len = 0; } int nXOffset = m_nWOffset; int nYOffset = m_nHOffset; int nLeft = nXOffset; int nRight = m_nWidth - nXOffset - 1; int nTop = nYOffset; int nBottom = m_nHeight - nYOffset - 1; int nXStartPos = nLeft; int nXEndPos = nRight; int nYStartPos = nTop; int nYEndPos = nBottom; int nBadPxlInfo = 0; int nPixelPos = 0; int nIdxI = 0; float fPVSum = 0.0f; float fDivisor = 0.0f; int nAvgPxlVal = CalcGlbAvgPxlValueBySamp(image, m_nWidth, m_nHeight, nXOffset, nYOffset); //校正最上面一行的坏点的像素值 if (0 < m_BadPixelMap[nTop].num_entries) { for (nIdxI = 0; nIdxI < m_BadPixelMap[nTop].num_entries; nIdxI++) { nBadPxlInfo = m_BadPixelMap[nTop].bad_pixel_num[nIdxI]; nPixelPos = nBadPxlInfo & OFFSET_MASK; fPVSum = 0.0f; fDivisor = 0.0f; //左边像素[nTop, nPixelPos - 1] if ((nLeft <= (nPixelPos - 1)) && ((nBadPxlInfo & NEIGHBOR_3) == 0)) { fPVSum += image[nTop * m_nWidth + nPixelPos - 1]; fDivisor += 1.0f; } //左下角像素[nTop + 1, nPixelPos - 1] if ((nLeft <= (nPixelPos - 1)) && ((nTop + 1) <= nBottom) && ((nBadPxlInfo & NEIGHBOR_5) == 0)) { fPVSum += 0.707f * image[(nTop + 1) * m_nWidth + nPixelPos - 1]; fDivisor += 0.707f; } //右边像素[nTop, nPixelPos + 1] if (((nPixelPos + 1) <= nRight) && ((nBadPxlInfo & NEIGHBOR_4) == 0)) { fPVSum += image[nTop * m_nWidth + nPixelPos + 1]; fDivisor += 1.0f; } //右下角像素[nTop + 1, nPixelPos + 1] if (((nPixelPos + 1) <= nRight) && ((nTop + 1) <= nBottom) && ((nBadPxlInfo & NEIGHBOR_7) == 0)) { fPVSum += 0.707f * image[(nTop + 1) * m_nWidth + nPixelPos + 1]; fDivisor += 0.707f; } //下边像素[nTop + 1, nPixelPos] if (((nTop + 1) <= nBottom) && ((nBadPxlInfo & NEIGHBOR_6) == 0)) { fPVSum += image[(nTop + 1) * m_nWidth + nPixelPos]; fDivisor += 1.0f; } if (0.9f < fDivisor) { image[nTop * m_nWidth + nPixelPos] = (int)(fPVSum / fDivisor); } else { image[nTop * m_nWidth + nPixelPos] = nAvgPxlVal; } } } //校正最下面一行坏点的像素值 if (0 < m_BadPixelMap[nBottom].num_entries) { for (nIdxI = 0; nIdxI < m_BadPixelMap[nBottom].num_entries; nIdxI++) { nBadPxlInfo = m_BadPixelMap[nBottom].bad_pixel_num[nIdxI]; nPixelPos = nBadPxlInfo & OFFSET_MASK; fPVSum = 0.0f; fDivisor = 0.0f; //左边像素[nBottom, nPixelPos - 1] if ((nLeft <= (nPixelPos - 1)) && ((nBadPxlInfo & NEIGHBOR_3) == 0)) { fPVSum += image[nBottom * m_nWidth + nPixelPos - 1]; fDivisor += 1.0f; } //左上角像素[nBottom - 1, nPixelPos - 1] if ((nLeft <= (nPixelPos - 1)) && (nTop <= (nBottom - 1)) && ((nBadPxlInfo & NEIGHBOR_0) == 0)) { fPVSum += 0.707f * image[(nBottom - 1) * m_nWidth + nPixelPos - 1]; fDivisor += 0.707f; } //右边像素[nBottom, nPixelPos + 1] if (((nPixelPos + 1) <= nRight) && ((nBadPxlInfo & NEIGHBOR_4) == 0)) { fPVSum += image[nBottom * m_nWidth + nPixelPos + 1]; fDivisor += 1.0f; } //右上角像素[nBottom - 1, nPixelPos + 1] if (((nPixelPos + 1) <= nRight) && (nTop <= (nBottom - 1)) && ((nBadPxlInfo & NEIGHBOR_2) == 0)) { fPVSum += 0.707f * image[(nBottom - 1) * m_nWidth + nPixelPos + 1]; fDivisor += 0.707f; } //上边像素[nBottom - 1, nPixelPos] if ((nTop <= (nBottom - 1)) && ((nBadPxlInfo & NEIGHBOR_1) == 0)) { fPVSum += image[(nBottom - 1) * m_nWidth + nPixelPos]; fDivisor += 1.0f; } if (0.9f < fDivisor) { image[nBottom * m_nWidth + nPixelPos] = (int)(fPVSum / fDivisor); } else { image[nBottom * m_nWidth + nPixelPos] = nAvgPxlVal; } } } //校正最左边列和最右边列的坏点的像素值 int nRow = 0; int nLeftBadPxlFlag = -1; int nRightBadPxlFlag = -1; for (nRow = nTop + 1; nRow < nBottom; nRow++) { nLeftBadPxlFlag = -1; nRightBadPxlFlag = -1; for (nIdxI = 0; nIdxI < m_BadPixelMap[nRow].num_entries; nIdxI++) { nBadPxlInfo = m_BadPixelMap[nRow].bad_pixel_num[nIdxI]; nPixelPos = nBadPxlInfo & OFFSET_MASK; if (nPixelPos == nLeft) { nLeftBadPxlFlag = nIdxI; } else if (nPixelPos == nRight) { nRightBadPxlFlag = nIdxI; } } //校正最左列的坏点的像素值 if (-1 < nLeftBadPxlFlag) { nBadPxlInfo = m_BadPixelMap[nRow].bad_pixel_num[nLeftBadPxlFlag]; nPixelPos = nBadPxlInfo & OFFSET_MASK; fPVSum = 0.0f; fDivisor = 0.0f; //上边像素[nRow - 1, nPixelPos] if ((nTop <= (nRow - 1)) && ((nBadPxlInfo & NEIGHBOR_1) == 0)) { fPVSum += image[(nRow - 1) * m_nWidth + nPixelPos]; fDivisor += 1.0f; } //右上角像素[nRow - 1, nPixelPos + 1] if (((nPixelPos + 1) <= nRight) && (nTop <= (nRow - 1)) && ((nBadPxlInfo & NEIGHBOR_2) == 0)) { fPVSum += 0.707f * image[(nRow - 1) * m_nWidth + nPixelPos + 1]; fDivisor += 0.707f; } //右边像素[nRow, nPixelPos + 1] if (((nPixelPos + 1) <= nRight) && ((nBadPxlInfo & NEIGHBOR_4) == 0)) { fPVSum += image[nRow * m_nWidth + nPixelPos + 1]; fDivisor += 1.0f; } //右下角像素[nRow + 1, nPixelPos + 1] if (((nPixelPos + 1) <= nRight) && ((nRow + 1) <= nBottom) && ((nBadPxlInfo & NEIGHBOR_7) == 0)) { fPVSum += 0.707f * image[(nRow + 1) * m_nWidth + nPixelPos + 1]; fDivisor += 0.707f; } //下边像素[nRow + 1, nPixelPos] if (((nRow + 1) <= nBottom) && ((nBadPxlInfo & NEIGHBOR_6) == 0)) { fPVSum += image[(nRow + 1) * m_nWidth + nPixelPos]; fDivisor += 1.0f; } if (0.9f < fDivisor) { image[nRow * m_nWidth + nPixelPos] = (int)(fPVSum / fDivisor); } else { image[nRow * m_nWidth + nPixelPos] = nAvgPxlVal; } } //校正最右列的坏点的像素值 if (-1 < nRightBadPxlFlag) { nBadPxlInfo = m_BadPixelMap[nRow].bad_pixel_num[nRightBadPxlFlag]; nPixelPos = nBadPxlInfo & OFFSET_MASK; fPVSum = 0.0f; fDivisor = 0.0f; //上边像素[nRow - 1, nPixelPos] if ((nTop <= (nRow - 1)) && ((nBadPxlInfo & NEIGHBOR_1) == 0)) { fPVSum += image[(nRow - 1) * m_nWidth + nPixelPos]; fDivisor += 1.0f; } //左上角像素[nRow - 1, nPixelPos - 1] if ((nLeft <= (nPixelPos - 1)) && (nTop <= (nRow - 1)) && ((nBadPxlInfo & NEIGHBOR_0) == 0)) { fPVSum += 0.707f * image[(nRow - 1) * m_nWidth + nPixelPos - 1]; fDivisor += 0.707f; } //左边像素[nRow, nPixelPos - 1] if ((nLeft <= (nPixelPos - 1)) && ((nBadPxlInfo & NEIGHBOR_3) == 0)) { fPVSum += image[nRow * m_nWidth + nPixelPos - 1]; fDivisor += 1.0f; } //左下角像素[nRow + 1, nPixelPos - 1] if ((nLeft <= (nPixelPos - 1)) && ((nRow + 1) <= nBottom) && ((nBadPxlInfo & NEIGHBOR_5) == 0)) { fPVSum += 0.707f * image[(nRow + 1) * m_nWidth + nPixelPos - 1]; fDivisor += 0.707f; } //下边像素[nRow + 1, nPixelPos] if (((nRow + 1) <= nBottom) && ((nBadPxlInfo & NEIGHBOR_6) == 0)) { fPVSum += image[(nRow + 1) * m_nWidth + nPixelPos]; fDivisor += 1.0f; } if (0.9f < fDivisor) { image[nRow * m_nWidth + nPixelPos] = (int)(fPVSum / fDivisor); } else { image[nRow * m_nWidth + nPixelPos] = nAvgPxlVal; } } } //校正其他坏点的像素值 for(line = nTop + 1; line < nBottom ; ++line) { /* Precalculate the column pointers */ p_line = image + (line * m_nWidth); p_next_line = p_line + m_nWidth; p_prev_line = p_line - m_nWidth; p_bad_pix_num = m_BadPixelMap[line].bad_pixel_num; unProcLineNum = 0; m_NewMap[line].p_Pix = &m_BadPixArray[unProcTotalNum]; for(pix_num = 0; pix_num < m_BadPixelMap[line].num_entries; ++pix_num) { bad_pix_num = *p_bad_pix_num++; bad_num = bad_pix_num & OFFSET_MASK; if (bad_num == nLeft || bad_num == nRight) { continue; } new_value = 0; divisor = 0; nPixelPos = bad_pix_num & NEIGHBOR_1; if(nPixelPos == 0) { new_value += *(p_prev_line + bad_num); divisor += 1.0f; } nPixelPos = bad_pix_num & NEIGHBOR_3; if(nPixelPos == 0 && 0 < bad_num) { new_value += *(p_line + bad_num - 1); divisor += 1.0f; } nPixelPos = bad_pix_num & NEIGHBOR_4; if(nPixelPos == 0) { new_value += *(p_line + bad_num + 1); divisor += 1.0f; } nPixelPos = bad_pix_num & NEIGHBOR_6; if(nPixelPos == 0) { new_value += *(p_next_line + bad_num); divisor += 1.0f; } if(divisor < 1.1f && divisor > 0.9f) { nPixelPos = bad_pix_num & NEIGHBOR_0; if(nPixelPos == 0 && bad_num > 0) { new_value += 0.707f * *(p_prev_line + bad_num - 1); divisor += 0.707f; } nPixelPos = bad_pix_num & NEIGHBOR_2; if(nPixelPos == 0) { new_value += 0.707f * *(p_prev_line + bad_num + 1); divisor += 0.707f; } nPixelPos = bad_pix_num & NEIGHBOR_7; if(nPixelPos == 0) { new_value += 0.707f * *(p_next_line + bad_num + 1); divisor += 0.707f; } nPixelPos = bad_pix_num & NEIGHBOR_5; if(nPixelPos == 0) { new_value += 0.707f * *(p_next_line + bad_num - 1); divisor += 0.707f; } } // At least one neighbor is good if(divisor > 1.9f) { w_new_value = (long)(new_value / divisor); //w_new_value = floor((new_value / divisor)+0.5); *(p_line + bad_num) = (WORD)w_new_value; } else { /* Added the pixel to the new bad pixel map */ unProcLineNum++; m_BadPixArray[unProcTotalNum] = bad_pix_num & OFFSET_MASK; unProcTotalNum = (unProcTotalNum + 1) % MAXI_BADPIX_COUNT; } } m_NewMap[line].len = unProcLineNum; } // // Fix the remaining bad pixels until no more bad pixels are left // while(unProcTotalNum > 0) { MarkBadPixels(m_nHeight, m_NewMap); unProcTotalNum = 0; for(line = 1; line < m_nHeight - 1; ++line) { /* Precalculate the column pointers */ p_line = image + line * m_nWidth; p_next_line = p_line + m_nWidth; p_prev_line = p_line - m_nWidth; p_bad_pix_num = m_NewMap[line].p_Pix; unProcLineNum = 0; m_NewMap[line].p_Pix = &m_BadPixArray[unProcTotalNum]; for(pix_num = 0; pix_num < (int)m_NewMap[line].len; ++pix_num) { bad_pix_num = *p_bad_pix_num++; bad_num = bad_pix_num & OFFSET_MASK; new_value = 0; divisor = 0; if (nLeft == bad_num || nRight == bad_num) { continue; } nPixelPos = bad_pix_num & NEIGHBOR_1; if(nPixelPos == 0) { new_value += *(p_prev_line + bad_num); divisor += 1.0f; } nPixelPos = bad_pix_num & NEIGHBOR_3; if(nPixelPos == 0 && 0 < bad_num) { new_value += *(p_line + bad_num - 1); divisor += 1.0f; } nPixelPos = bad_pix_num & NEIGHBOR_4; if(nPixelPos == 0) { new_value += *(p_line + bad_num + 1); divisor += 1.0f; } nPixelPos = bad_pix_num & NEIGHBOR_6; if(nPixelPos == 0) { new_value += *(p_next_line + bad_num); divisor += 1.0f; } if(divisor < 1.1f && divisor > 0.9f) { nPixelPos = bad_pix_num & NEIGHBOR_0; if(nPixelPos == 0 && 0 < bad_num) { new_value += 0.707f * *(p_prev_line + bad_num - 1); divisor += 0.707f; } nPixelPos = bad_pix_num & NEIGHBOR_2; if(nPixelPos == 0) { new_value += 0.707f * *(p_prev_line + bad_num + 1); divisor += 0.707f; } nPixelPos = bad_pix_num & NEIGHBOR_7; if(nPixelPos == 0) { new_value += 0.707f * *(p_next_line + bad_num + 1); divisor += 0.707f; } nPixelPos = bad_pix_num & NEIGHBOR_5; if(nPixelPos == 0 && 0 < bad_num) { new_value += 0.707f * *(p_next_line + bad_num - 1); divisor += 0.707f; } } if(divisor > 1.9f) { //w_new_value = floor((new_value / divisor)+0.5); w_new_value = (long)((new_value / divisor)+0.5); *(p_line + bad_num) = (WORD)w_new_value; } else { /* Goes to the new map */ unProcLineNum++; m_BadPixArray[unProcTotalNum] = bad_num; unProcTotalNum = (unProcTotalNum + 1) % MAXI_BADPIX_COUNT; } } m_NewMap[line].len = unProcLineNum; } } return; } #define CHECK_NEIGHBOR_NEW_U(a, b) \ while(ju < New_Map[a].len) \ { \ jj = New_Map[a].p_Pix[ju] & OFFSET_MASK; \ if(jj == (b))\ bad_neighbor |= NEIGHBOR_1;\ else if(jj == (b - 1)) \ bad_neighbor |= NEIGHBOR_0; \ else if(jj == (b + 1)) \ bad_neighbor |= NEIGHBOR_2; \ if(jj >= (b + 1)){ \ ju = ju ? ju - 1 : ju;\ break; }\ if((ju + 1) >= New_Map[a].len) break; \ ju++;\ } #define CHECK_NEIGHBOR_U(a, b) \ while(ju < m_BadPixelMap[a].num_entries) \ { \ jj = m_BadPixelMap[a].bad_pixel_num[ju] & OFFSET_MASK; \ if(jj == (b))\ bad_neighbor |= NEIGHBOR_1;\ else if(jj == (b - 1)) \ bad_neighbor |= NEIGHBOR_0; \ else if(jj == (b + 1)) \ bad_neighbor |= NEIGHBOR_2; \ if(jj >= (b + 1)){ \ ju = ju ? ju - 1 : ju;\ break; } \ if((ju + 1) >= m_BadPixelMap[a].num_entries) break; \ ju++;\ } #define CHECK_NEIGHBOR_NEW_D(a, b) \ while(jd < New_Map[a].len) \ { \ jj = New_Map[a].p_Pix[jd] & OFFSET_MASK; \ if(jj == (long)(b))\ bad_neighbor |= NEIGHBOR_6;\ else if(jj == (long)(b - 1)) \ bad_neighbor |= NEIGHBOR_5; \ else if(jj == (long)(b + 1)) \ bad_neighbor |= NEIGHBOR_7; \ if(jj >= (long)(b + 1)){ \ jd = jd ? jd - 1 : jd;\ break;} \ if( ( jd + 1 ) >= New_Map[ a ].len ) break; \ jd++;\ } #define CHECK_NEIGHBOR_D(a, b) \ while(jd < m_BadPixelMap[a].num_entries )\ { \ jj = m_BadPixelMap[a].bad_pixel_num[jd] & OFFSET_MASK; \ if(jj == (b))\ bad_neighbor |= NEIGHBOR_6;\ else if(jj == (b - 1)) \ bad_neighbor |= NEIGHBOR_5; \ else if(jj == (b + 1)) \ bad_neighbor |= NEIGHBOR_7; \ if(jj >= (b + 1)){ \ jd = jd ? jd - 1 : jd;\ break;}\ if((jd + 1) >= m_BadPixelMap[a].num_entries ) break; \ jd++;\ } void CPixMatrix::MarkBadPixels(int NumLines, PIX_MAP *New_Map) { long i, ju, jd; long jj; long pix_num; long *p_bad_pix; long bad_pix_num; long bad_neighbor; for(i = 1; i < NumLines - 1; ++i) { p_bad_pix = New_Map[i].p_Pix; for(pix_num = 0, ju = 0, jd = 0; pix_num < (int)New_Map[i].len; ++pix_num) { bad_pix_num = *p_bad_pix & OFFSET_MASK; bad_neighbor = 0; CHECK_NEIGHBOR_NEW_U((long)(i - 1), bad_pix_num); if((*(p_bad_pix - 1) & OFFSET_MASK) == bad_pix_num - 1) bad_neighbor |= NEIGHBOR_3; if((*(p_bad_pix + 1) & OFFSET_MASK) == bad_pix_num + 1) bad_neighbor |= NEIGHBOR_4; CHECK_NEIGHBOR_NEW_D(i + 1, bad_pix_num); *p_bad_pix++ = bad_pix_num | bad_neighbor; } } } // /****************************************************************************/ // /* Use the upper byte of the bad pixel map offset to pre-mark bad pixels // that have adjacent bad pixels */ // // void CPixMatrix::MarkBadAdjacentPixels() // { // long i, ju, jd; // long jj; // long pix_num; // long *p_bad_pix; // long bad_pix_num; // long bad_neighbor; // // /* // * Mark the bad pixel map for high-resolution image // */ // if(m_BadPixelMap == NULL) return; // int // for(i = 1; i < (m_nHeight - 1); ++i) // { // p_bad_pix = m_BadPixelMap[i].bad_pixel_num; // for(pix_num = 0, ju = 0, jd = 0 ; pix_num < m_BadPixelMap[i].num_entries ; pix_num++) // { // bad_pix_num = *p_bad_pix & OFFSET_MASK; // bad_neighbor = 0; // CHECK_NEIGHBOR_U((long)(i - 1), bad_pix_num); // if((*(p_bad_pix - 1) & OFFSET_MASK) == bad_pix_num - 1) // { // bad_neighbor |= NEIGHBOR_3; // } // if((*(p_bad_pix + 1) & OFFSET_MASK) == bad_pix_num + 1) // { // bad_neighbor |= NEIGHBOR_4; // } // CHECK_NEIGHBOR_D((long)(i + 1), bad_pix_num); // *p_bad_pix++ = bad_pix_num | bad_neighbor; // } // } // } /****************************************************************************/ /* Use the upper byte of the bad pixel map offset to pre-mark bad pixels that have adjacent bad pixels */ //Modified by Alex Stocks on 2011/01/30 void CPixMatrix::MarkBadAdjacentPixels() { if(m_BadPixelMap == NULL) { return; } long i, ju, jd; long jj; long pix_num; long *p_bad_pix; long bad_pix_num; long bad_neighbor; int a = 0; int b = 0; /* * Mark the bad pixel map for high-resolution image */ int nXOffset = 0 < m_nWOffset ? m_nWOffset : 0; int nXStartPos = nXOffset; int nXEndPos = m_nWidth - nXOffset; int nYOffset = 0 < m_nHOffset ? m_nHOffset : 0; int nYStartPos = nYOffset; int nYEndPos = m_nHeight - nYOffset; int nLeft = nXStartPos; int nRight = nXEndPos - 1; int nTop = nYStartPos; int nBottom = nYEndPos - 1; //for(i = 1; i < (m_nHeight - 1); ++i) for (i = nYStartPos; i < nYEndPos; i++) { p_bad_pix = m_BadPixelMap[i].bad_pixel_num; for(pix_num = 0, ju = 0, jd = 0 ; pix_num < m_BadPixelMap[i].num_entries ; pix_num++) { bad_pix_num = *p_bad_pix & OFFSET_MASK; bad_neighbor = 0; //CHECK_NEIGHBOR_U((long)(i - 1), bad_pix_num); a = i - 1; //上一行 b = bad_pix_num; //列 //对每个坏点像素的上一行的三个位置进行检查 while((nTop <= a) && (ju < m_BadPixelMap[a].num_entries)) { jj = m_BadPixelMap[a].bad_pixel_num[ju] & OFFSET_MASK; if(jj == (b)) {//上面 bad_neighbor |= NEIGHBOR_1; } else if(nLeft <= (b - 1) && ((b - 1) == jj)) {//左上 bad_neighbor |= NEIGHBOR_0; } else if((b + 1) <= nRight && ((b + 1) == jj)) {//右上 bad_neighbor |= NEIGHBOR_2; } if((b + 1) <= jj) { ju = ju ? ju - 1 : ju; break; } if(m_BadPixelMap[a].num_entries <= (ju + 1)) { break; } ju++; } //对坏点像素左边和右边进行检查 if((nLeft <= (b - 1)) && ((*(p_bad_pix - 1) & OFFSET_MASK) == bad_pix_num - 1)) {//左边 bad_neighbor |= NEIGHBOR_3; } if(((b + 1) <= nRight) && ((*(p_bad_pix + 1) & OFFSET_MASK) == bad_pix_num + 1)) {//右边 bad_neighbor |= NEIGHBOR_4; } //CHECK_NEIGHBOR_D((long)(i + 1), bad_pix_num); a = i + 1; //下一行 b = bad_pix_num; //列 //对坏点像素的下一行进行检查 while((a <= nBottom) && (jd < m_BadPixelMap[a].num_entries) ) { jj = m_BadPixelMap[a].bad_pixel_num[jd] & OFFSET_MASK; if(jj == (b)) {//下面 bad_neighbor |= NEIGHBOR_6; } else if(nLeft <= (b - 1) && (jj == (b - 1))) {//左下 bad_neighbor |= NEIGHBOR_5; } else if((b + 1) <= nRight && (jj == (b + 1))) {//右下 bad_neighbor |= NEIGHBOR_7; } if(jj >= (b + 1)) { jd = jd ? jd - 1 : jd; break; } if((jd + 1) >= m_BadPixelMap[a].num_entries ) { break; } jd++; } //bad_neighbor记录了坏点位置8邻域内所有的坏点的位置 *p_bad_pix++ = bad_pix_num | bad_neighbor; } } } bool CPixMatrix::LoadBadPixelMap(const char *fileName) { //BAD_PIXEL_ENTRY **theMap = &m_BadPixelMap; strcpy(m_charFilename, fileName); FILE *fp; int num_entries; int entry; int line_num; int file_line_num; long *p_bad_pixels; bool status = TRUE; long bad_pixel_num = 0; char *data_in = NULL; char *p_token; long num_bad_pixels = 0; /* Hopefully, the largest line in a bad pix map */ // data_in = (char *)malloc(MAX_PIX_MAP_LINE); data_in = new char [MAX_PIX_MAP_LINE]; if(data_in == NULL) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: malloc of data_in failed."); } fp = fopen(fileName, "rb"); if(fp == NULL) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Open of file : %s failed.", fileName); } else { if(m_BadPixelMap != NULL) { FreeBadPixelMap(); } //m_BadPixelMap = (BAD_PIXEL_ENTRY *)calloc(m_nHeight, sizeof(BAD_PIXEL_ENTRY)); m_BadPixelMap = new BAD_PIXEL_ENTRY [m_nHeight*sizeof(BAD_PIXEL_ENTRY)]; if(m_BadPixelMap == NULL) { // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Malloc of m_BadPixelMap failed."); status = FALSE; } else { for (int i=0;i m_nWidth) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Pixel map read error for col %d; " // "num_entries (%d) > line_size (%d)", line_num, num_entries, m_nWidth); } /* Tokenize the header */ p_token = strtok(data_in, ":"); if(status == TRUE) { /* Create the correct size bad pixel map entry */ //(m_BadPixelMap)[line_num].bad_pixel_num = (long *)malloc((num_entries + 1) * sizeof(long)); m_BadPixelMap[line_num].bad_pixel_num = new long [(num_entries+1)*sizeof(long)]; if( (m_BadPixelMap)[line_num].bad_pixel_num == NULL) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Malloc of p_bad_pixels for line %d failed.", line_num); } else { memset( (m_BadPixelMap)[line_num].bad_pixel_num, 0, (num_entries + 1) * sizeof(long)); p_bad_pixels = (m_BadPixelMap)[line_num].bad_pixel_num; (m_BadPixelMap)[line_num].num_entries = num_entries; /* Fill in the array */ for(entry = 0 ; entry < num_entries ; ++entry) { /* * The remainder of each line of the Bad Pixel File consists * of numbers indicating the x-coordinate value of the bad * pixels. They should be in ascending order. None of them * should be greater than capture_config.line_size. */ p_token = strtok(NULL, ","); if((p_token == NULL) || (sscanf(p_token, "%ld,", &bad_pixel_num) != 1)) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Read failure on pixel entry %d.", entry); } else { if(bad_pixel_num > m_nWidth) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Bad value (%ld) on pixel entry %d " // "exceeds line_size (%d)", // bad_pixel_num, entry, m_nWidth); } else { p_bad_pixels[entry] = bad_pixel_num; num_bad_pixels++; } } } } } line_num++; } /* Not a bad pixel entry; This is a bad line in the file */ else { if(strstr(data_in, "synthseam")) continue; else status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Read of entry for line_num %d failed", line_num ); // DRUTIL_LogMessage( LOG_LEVEL_ERROR, " Line_num %d is: <%s>", line_num, data_in ); } } else { // file read error here or end of file. break; } } } if(status == TRUE) { if(num_bad_pixels > MAX_BAD_PIXELS) { // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Bad pixel map exceeds limit (%ld) : %ld pixels", // MAX_BAD_PIXELS, num_bad_pixels); } } if(fp != NULL) { fclose(fp); } if(data_in != NULL) { delete [] data_in; } if(status != TRUE) { FreeBadPixelMap(); } else { /////////////////////////新方法-基于二值图坏线识别 BadLineRecognize(); } return status; } bool CPixMatrix::LoadBadPixelMapChar(char* data_char, bool bNew) { //BAD_PIXEL_ENTRY **theMap = &m_BadPixelMap; // FILE *fp; int num_entries; int entry; int line_num; int file_line_num; long *p_bad_pixels; bool status = TRUE; long bad_pixel_num = 0; char *data_in = NULL; char *p_token; long num_bad_pixels = 0; // char *data_temp; long char_readcount = 0; /* Hopefully, the largest line in a bad pix map */ // data_in = (char *)malloc(MAX_PIX_MAP_LINE); // data_in = new char [MAX_PIX_MAP_LINE]; // if(data_in == NULL) { // status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: malloc of data_in failed."); // } // fp = fopen(fileName, "rb"); if(data_char == NULL) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Open of file : %s failed.", fileName); } else { if(m_BadNewPixelMap != NULL) { FreeBadPixelMap(); } //m_BadPixelMap = (BAD_PIXEL_ENTRY *)calloc(m_nHeight, sizeof(BAD_PIXEL_ENTRY)); m_BadNewPixelMap = new BAD_PIXEL_ENTRY [m_nHeight*sizeof(BAD_PIXEL_ENTRY)]; if(m_BadNewPixelMap == NULL) { // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Malloc of m_BadPixelMap failed."); status = FALSE; } } /* Data structures created OK and file is open, let's roll */ if(status == TRUE) { line_num = 0; while((line_num < m_nHeight) && (status == TRUE)) { data_in = strtok(data_char+char_readcount, "\n"); char_readcount += long(strlen( data_in )+1); if(data_in!= NULL) { // Each line in bad_pixel.map begins with "linenum,num_entries: " if(sscanf(data_in, "%d,%d: ", &file_line_num, &num_entries) == 2) { // Verify the line number read matches the line num we are on if(line_num != file_line_num) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Pixel map read error for col %d.", line_num); } // Verify that num_entries is not larger than pixels-per-line if(num_entries > m_nWidth) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Pixel map read error for col %d; " // "num_entries (%d) > line_size (%d)", line_num, num_entries, m_nWidth); } /* Tokenize the header */ p_token = strtok(data_in, ":"); if(status == TRUE) { /* Create the correct size bad pixel map entry */ //(m_BadPixelMap)[line_num].bad_pixel_num = (long *)malloc((num_entries + 1) * sizeof(long)); m_BadNewPixelMap[line_num].bad_pixel_num = new long [(num_entries+1)*sizeof(long)]; if( (m_BadNewPixelMap)[line_num].bad_pixel_num == NULL) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Malloc of p_bad_pixels for line %d failed.", line_num); } else { memset( (m_BadNewPixelMap)[line_num].bad_pixel_num, 0, (num_entries + 1) * sizeof(long)); p_bad_pixels = (m_BadNewPixelMap)[line_num].bad_pixel_num; (m_BadNewPixelMap)[line_num].num_entries = num_entries; /* Fill in the array */ for(entry = 0 ; entry < num_entries ; ++entry) { /* * The remainder of each line of the Bad Pixel File consists * of numbers indicating the x-coordinate value of the bad * pixels. They should be in ascending order. None of them * should be greater than capture_config.line_size. */ p_token = strtok(NULL, ","); if((p_token == NULL) || (sscanf(p_token, "%ld,", &bad_pixel_num) != 1)) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Read failure on pixel entry %d.", entry); } else { if(bad_pixel_num > m_nWidth) { status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Bad value (%ld) on pixel entry %d " // "exceeds line_size (%d)", // bad_pixel_num, entry, m_nWidth); } else { p_bad_pixels[entry] = bad_pixel_num; num_bad_pixels++; } } } } } line_num++; } /* Not a bad pixel entry; This is a bad line in the file */ else { if(strstr(data_in, "synthseam")) continue; else status = FALSE; // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Read of entry for line_num %d failed", line_num ); // DRUTIL_LogMessage( LOG_LEVEL_ERROR, " Line_num %d is: <%s>", line_num, data_in ); } } else { // file read error here or end of file. break; } } } if(status == TRUE) { if(num_bad_pixels > MAX_BAD_PIXELS) { // DRUTIL_LogMessage( LOG_LEVEL_ERROR, "ERROR: Bad pixel map exceeds limit (%ld) : %ld pixels", // MAX_BAD_PIXELS, num_bad_pixels); } } if(status != TRUE) { FreeBadNewPixelMap(); } if(!bNew) { if(m_BadPixelMap != NULL) { FreeBadPixelMap(); } m_BadPixelMap = m_BadNewPixelMap; m_BadNewPixelMap = NULL; } return status; } bool CPixMatrix::SaveBadPixelMap(const char *fileName) { FILE *fp; char *data_out = NULL; long char_count = 0; bool status = TRUE; long line; long bad_pix_num; long bad_num; long pix_num; long *p_bad_pix_num; long char_length; data_out = new char [MAXI_BADPIX_COUNT*2]; for(line = 0 ; line < m_nHeight; ++line) { char_length = sprintf(data_out+char_count,"%d,%d:",line,m_BadPixelMap[line].num_entries); char_count += char_length; p_bad_pix_num = m_BadPixelMap[line].bad_pixel_num;// for(pix_num = 0; pix_num < m_BadPixelMap[line].num_entries; ++pix_num) { bad_pix_num = *p_bad_pix_num++; bad_num = bad_pix_num & OFFSET_MASK; char_length = sprintf(data_out+char_count,"%d,",bad_num); char_count += char_length; } char_length = sprintf(data_out+char_count,"\n"); char_count += char_length; } fp = fopen(fileName, "wb"); if (fwrite(data_out,1,char_count,fp)!=char_count){ status = FALSE; } fclose(fp); if(m_BadPixelMap == NULL) { status = FALSE; } else { //////////////////////////////////////////坏线自动识别 BadLineRecognize(); } if(data_out != NULL) { delete [] data_out; } return status; } int CPixMatrix::BadGridLineCorrect1( unsigned short *pImage, int nLineDirection, int nEntries, int nStartPoint, int nEndPoint, int nWidth, int nHeight) { if( !pImage || nEntries < m_nHOffset || nEntries > nHeight - m_nHOffset ) return -1; memcpy( m_TempImage, pImage,sizeof(unsigned short) * m_nWidth * m_nHeight ); if( nEntries -2 < m_nHOffset) { for( int i = nStartPoint; i < nEndPoint; i++ ) { pImage[ (nEntries) * nWidth + i] = m_TempImage[( nEntries +2 ) * nWidth + i] ; } } else if( nEntries + 2 > nHeight - m_nHOffset ) { for( int i = nStartPoint; i < nEndPoint; i++ ) { pImage[ (nEntries) * nWidth + i] = m_TempImage[( nEntries -2 ) * nWidth + i] ; } } else { for( int i = nStartPoint; i < nEndPoint; i++ ) { pImage[ (nEntries) * nWidth + i] = 0.5*( m_TempImage[( nEntries +2 ) * nWidth + i] + m_TempImage[( nEntries -2 ) * nWidth + i] ); } } return 0; } //¨¨£¤??è¨???????ê??|ì??3????D?ê?y?ê?¨o¨2??à?|ì???ê?zhaoyiru,2017.05.09 int CPixMatrix::BadGridLineCorrect2( unsigned short *pImage, int nLineDirection, int nEntries, int nStartPoint, int nEndPoint, int nWidth, int nHeight)//¨o¨2??à { if( !pImage || nEntries < m_nWOffset || nEntries > nWidth - m_nWOffset ) return -1; memcpy( m_TempImage, pImage,sizeof(unsigned short) * m_nWidth * m_nHeight ); if( nEntries -2 <= m_nWOffset) { for( int i = nStartPoint; i < nEndPoint; i++ ) { pImage[i * nWidth + nEntries] =m_TempImage[( i ) * nWidth + nEntries + 2]; } } else if( nEntries + 2 > nHeight - m_nWOffset ) { for( int i = nStartPoint; i < nEndPoint; i++ ) { pImage[i * nWidth + nEntries] =m_TempImage[( i ) * nWidth + nEntries - 2]; } } else { for( int i = nStartPoint; i < nEndPoint; i++ ) { pImage[i * nWidth + nEntries] = 0.5*( m_TempImage[( i ) * nWidth + nEntries - 2] + m_TempImage[( i ) * nWidth + nEntries + 2 ] ); } } return 0; } //¨¨£¤??è¨???o¨??ê??|ì???t???D?ê?y?ê??????|ì???ê? zhaoyiru,2017.05.09 int CPixMatrix::BadGridLineCorrect3( unsigned short *pImage, int nLineDirection, int nEntries, int nStartPoint, int nEndPoint, int nWidth, int nHeight) { if( !pImage || nEntries < m_nHOffset+2 || nEntries > nHeight -m_nHOffset-3 ) return -1; if ( nStartPoint < m_nWOffset + 2 ) nStartPoint = m_nWOffset + 2; if ( nEndPoint > m_nWOffset -3) nEndPoint = nWidth- m_nWOffset -3; memcpy( m_TempImage, pImage,sizeof(unsigned short) * m_nWidth * m_nHeight ); const float coef1=0.25f; const float coef2=0.5f;//0.67f; const float coef3=0.5f;//0.33f; const float coef4=1.0f; const float coef5=2.0f; const float coef6=1.0f; for( int i = nStartPoint; i < nEndPoint; i++ ) { int nA,nB,nC,nA1, nB1,nC1; nA1 = coef1*(m_TempImage[(nEntries-1)*m_nWidth + i-2]*coef4 + m_TempImage[(nEntries-1)*m_nWidth + i-1]*coef5 + m_TempImage[(nEntries-1)*m_nWidth + i]*coef6 - m_TempImage[(nEntries+1)*m_nWidth + i]*coef4 - m_TempImage[(nEntries+1)*m_nWidth + i+1]*coef5 - m_TempImage[(nEntries+1)*m_nWidth + i +2]*coef6); nB1 = coef1*(m_TempImage[(nEntries-1)*m_nWidth + i-1 ]*coef4 + m_TempImage[(nEntries-1)*m_nWidth + i]*coef5 + m_TempImage[(nEntries-1)*m_nWidth + i+1]*coef6- m_TempImage[(nEntries+1)*m_nWidth + i-1 ]*coef4 - m_TempImage[(nEntries+1)*m_nWidth + i]*coef5 - m_TempImage[(nEntries+1)*m_nWidth + i+1]*coef6); nC1 = coef1*(m_TempImage[(nEntries-1)*m_nWidth + i]*coef4 + m_TempImage[(nEntries-1)*m_nWidth + i+1]*coef5 + m_TempImage[(nEntries-1)*m_nWidth + i +2]*coef6 - m_TempImage[(nEntries+1)*m_nWidth + i-2]*coef4 - m_TempImage[(nEntries+1)*m_nWidth + i-1]*coef5 - m_TempImage[(nEntries+1)*m_nWidth + i]*coef6); nA = nA1*nA1; nB = nB1*nB1; nC = nC1*nC1; if( nA <= nB && nA<= nC ) { pImage[(nEntries)*m_nWidth + i] = coef1*coef2*(m_TempImage[(nEntries-1)*m_nWidth + i-2]*coef4 + m_TempImage[(nEntries-1)*m_nWidth + i-1]*coef5 + m_TempImage[(nEntries-1)*m_nWidth + i]*coef6)+ coef1*coef3*(m_TempImage[(nEntries+1)*m_nWidth + i]*coef4 + m_TempImage[(nEntries+1)*m_nWidth + i+1]*coef5 +m_TempImage[(nEntries+1)*m_nWidth + i +2]*coef6); } else if( nB<= nC ) { pImage[(nEntries)*m_nWidth + i] = coef1*coef2*(m_TempImage[(nEntries-1)*m_nWidth + i-1 ]*coef4 + m_TempImage[(nEntries-1)*m_nWidth + i]*coef5 + m_TempImage[(nEntries-1)*m_nWidth + i+1]*coef6)+ coef1*coef3*( m_TempImage[(nEntries+1)*m_nWidth + i-1 ]*coef4 + m_TempImage[(nEntries+1)*m_nWidth + i]*coef5 + m_TempImage[(nEntries+1)*m_nWidth + i+1]*coef6); } else { pImage[(nEntries)*m_nWidth + i] = coef1*coef2*(m_TempImage[(nEntries-1)*m_nWidth + i]*coef4 + m_TempImage[(nEntries-1)*m_nWidth + i+1]*coef5 + m_TempImage[(nEntries-1)*m_nWidth + i +2]*coef6)+ coef1*coef3*(m_TempImage[(nEntries+1)*m_nWidth + i-2]*coef4 + m_TempImage[(nEntries+1)*m_nWidth + i-1]*coef5 + m_TempImage[(nEntries+1)*m_nWidth + i]*coef6); } } return 0; } //¨¨£¤??è¨???o¨??ê??|ì???t???D?ê?y?ê?¨o¨2??à?|ì???ê?zhaoyiru,2017.05.09 int CPixMatrix::BadGridLineCorrect4( unsigned short *pImage, int nLineDirection, int nEntries, int nStartPoint, int nEndPoint, int nWidth, int nHeight) { if( !pImage || nEntries < m_nWOffset+3 || nEntries > nHeight -m_nWOffset-4 ) return -1; if ( nStartPoint < m_nHOffset + 3 ) nStartPoint = m_nHOffset + 3; if ( nEndPoint > m_nHOffset -4) nEndPoint = nHeight-m_nHOffset -4; memcpy( m_TempImage, pImage,sizeof(unsigned short) * m_nWidth * m_nHeight ); const float coef1=0.25f; const float coef2=0.5f;//0.67f; const float coef3=0.5f;//0.33f; const float coef4=1.0f; const float coef5=2.0f; const float coef6=1.0f; for( int i = nStartPoint; i < nEndPoint; i++ ) { int nA,nB,nC,nA1, nB1,nC1; nA1 = coef1*(m_TempImage[(i-2)*m_nWidth + nEntries-1]*coef4 + m_TempImage[(i-1)*m_nWidth + nEntries-1]*coef5 + m_TempImage[(i)*m_nWidth + nEntries-1]*coef6 - m_TempImage[(i)*m_nWidth + nEntries+1]*coef4 - m_TempImage[(i+1)*m_nWidth + nEntries+1]*coef5 - m_TempImage[(i+2)*m_nWidth + nEntries +1]*coef6); nB1 = coef1*(m_TempImage[(i-1)*m_nWidth + nEntries-1 ]*coef4 + m_TempImage[(i)*m_nWidth + nEntries-1]*coef5 + m_TempImage[(i+1)*m_nWidth + nEntries-1]*coef6- m_TempImage[(i-1)*m_nWidth + nEntries+1 ]*coef4 - m_TempImage[(i)*m_nWidth + nEntries+1]*coef5 - m_TempImage[(i+1)*m_nWidth + nEntries+1]*coef6); nC1 = coef1*(m_TempImage[(i)*m_nWidth + nEntries-1]*coef4 + m_TempImage[(i+1)*m_nWidth + nEntries-1]*coef5 + m_TempImage[(i+2)*m_nWidth + nEntries-1]*coef6 - m_TempImage[(i-2)*m_nWidth + nEntries+1 ]*coef4 - m_TempImage[(i-1)*m_nWidth + nEntries+1]*coef5 - m_TempImage[(i)*m_nWidth + nEntries+1]*coef6); nA = nA1*nA1; nB = nB1*nB1; nC = nC1*nC1; if( nA <= nB && nA<= nC ) { pImage[(i)*m_nWidth + nEntries] = coef1*coef2*(m_TempImage[(i-2)*m_nWidth + nEntries-1]*coef4 + m_TempImage[(i-1)*m_nWidth + nEntries-1]*coef5 + m_TempImage[(i)*m_nWidth + nEntries-1]*coef6)+ coef1*coef3*(m_TempImage[(i)*m_nWidth + nEntries+1]*coef4 + m_TempImage[(i+1)*m_nWidth + nEntries+1]*coef5 + m_TempImage[(i+2)*m_nWidth + nEntries +1]*coef6); } else if( nB<= nC ) { pImage[(i)*m_nWidth + nEntries] = coef1*coef2*(m_TempImage[(i-1)*m_nWidth + nEntries-1 ]*coef4 + m_TempImage[(i)*m_nWidth + nEntries-1]*coef5 + m_TempImage[(i+1)*m_nWidth + nEntries-1]*coef6)+ coef1*coef3*(m_TempImage[(i-1)*m_nWidth + nEntries+1 ]*coef4 + m_TempImage[(i)*m_nWidth + nEntries+1]*coef5 + m_TempImage[(i+1)*m_nWidth + nEntries+1]*coef6 ); } else { pImage[(i)*m_nWidth + nEntries] = coef1*coef2*(m_TempImage[(i)*m_nWidth + nEntries-1]*coef4 + m_TempImage[(i+1)*m_nWidth + nEntries-1]*coef5 + m_TempImage[(i+2)*m_nWidth + nEntries-1]*coef6)+ coef1*coef3*(m_TempImage[(i-2)*m_nWidth + nEntries+1 ]*coef4 + m_TempImage[(i-2)*m_nWidth + nEntries+1]*coef5 + m_TempImage[(i)*m_nWidth + nEntries+1]*coef6); } } return 0; } void CPixMatrix::BadLineRecognize() { //////////////////////////////////////////坏线自动识别 long BadPixNum; long BadNum; memset( m_TempImage, 0, sizeof(unsigned short) * m_nWidth * m_nHeight ); memset( m_TempImage1, 0, sizeof(unsigned short) * m_nWidth * m_nHeight ); memset( m_datalen, -1, sizeof(int) * (int( (MAXI_BADPIX_COUNT - MAX_PIX_MAP_LINE) / m_nLinePoint)) ); for ( int i = m_nHOffset + 2; i < m_nHeight - m_nHOffset - 2; i++ ) { m_pBadPixNum = m_BadPixelMap[ i ].bad_pixel_num; if ( m_BadPixelMap[ i ].num_entries > 0 ) { for ( int j = 0; j < m_BadPixelMap[ i ].num_entries; j++ ) { BadPixNum = *m_pBadPixNum++; BadNum = BadPixNum & OFFSET_MASK; if ( BadNum > 1 && BadNum < m_nWidth - 1 ) m_TempImage[ i * m_nWidth + BadNum ] = 65535; } } } /////////////////////按行标记坏线,水平坏线 //char *data_out = NULL;改为m_datalen; int linedirection; //m_datalen = new char [ 40000 ]; int count = 0; for ( int i = m_nHOffset; i < m_nHeight - m_nHOffset; i++ ) { for ( int j = m_nWOffset + 2; j < m_nWidth - m_nWOffset - 2; j++ ) { m_TempImage1[ i * m_nWidth + j ] = ( m_TempImage[ i * m_nWidth + j - 2 ] + m_TempImage[ i * m_nWidth + j - 1 ] + m_TempImage[ i * m_nWidth + j ] + m_TempImage[ i * m_nWidth + j + 1 ] + m_TempImage[ i * m_nWidth + j + 2 ] ) / 5; if ( m_TempImage1[ i * m_nWidth + j ] < 40000 ) m_TempImage1[ i * m_nWidth + j ] = 0; else m_TempImage1[ i * m_nWidth + j ] = 65535; } int tempcount = 0; for ( int p = m_nWOffset; p < m_nWidth - m_nWOffset; p++ ) { if ( m_TempImage1[ i * m_nWidth + p ] == 65535 ) tempcount++; } int minX = 0; int maxX = 0; if ( tempcount > m_nLinePoint )//add by chen 2015-1-13 judge condition change from 300 to 50 { for ( int k = m_nWOffset; k < m_nWidth - m_nWOffset; k++ ) { if ( m_TempImage1[ i * m_nWidth + k ] == 65535 ) { minX = k; break; } } for ( int k1 = m_nWidth - m_nWOffset - 1; k1 > m_nWOffset; k1-- ) { if ( m_TempImage1[ i * m_nWidth + k1 ] == 65535 ) { maxX = k1; break; } } linedirection = 0; //char_length = sprintf( m_datalen + char_count, "%d,%d:%d,%d", linedirection, i, minX - 2, maxX + 2 ); //char_count += char_length; //char_length = sprintf( m_datalen + char_count, "\n" ); //char_count += char_length; m_datalen[ count ] = linedirection; m_datalen[ count + 1 ] = i; m_datalen[ count + 2 ] = minX - 2; m_datalen[ count + 3 ] = maxX + 2; count += 4; } } ////////////////////////////按列标记坏线--竖直坏线 memset( m_TempImage1, 0, sizeof(unsigned short) * m_nWidth * m_nHeight ); for ( int i = m_nWOffset; i < m_nWidth - m_nWOffset; i++ ) { for ( int j = m_nHOffset + 2; j < m_nHeight - m_nHOffset - 2; j++ ) { m_TempImage1[ j * m_nWidth + i ] = ( m_TempImage[ ( j - 2 ) * m_nWidth + i ] + m_TempImage[ ( j - 1 ) * m_nWidth + i ] + m_TempImage[ j * m_nWidth + i ] + m_TempImage[ ( j + 1 ) * m_nWidth + i ] + m_TempImage[ ( j + 2 ) * m_nWidth + i ] ) / 5; if ( m_TempImage1[ j * m_nWidth + i ] < 40000 ) m_TempImage1[ j * m_nWidth + i ] = 0; else m_TempImage1[ j * m_nWidth + i ] = 65535; } int tempcount = 0; for ( int p = m_nHOffset; p < m_nHeight - m_nHOffset; p++ ) { if ( m_TempImage1[ p * m_nWidth + i ] == 65535 ) tempcount++; } int minY = 0; int maxY = 0; if ( tempcount > m_nLinePoint )//add by chen 2015-1-13 judge condition change from 300 to 50 { for ( int k = m_nHOffset; k < m_nHeight - m_nHOffset; k++ ) { if ( m_TempImage1[ k * m_nWidth + i ] == 65535 ) { minY = k; break; } } for ( int k1 = m_nHeight - m_nHOffset - 1; k1 > m_nHOffset; k1-- ) { if ( m_TempImage1[ k1 * m_nWidth + i ] == 65535 ) { maxY = k1; break; } } linedirection = 1; //char_length = sprintf( m_datalen + char_count, "%d,%d:%d,%d", linedirection, i, minY - 2, maxY + 2 ); //char_count += char_length; //char_length = sprintf( m_datalen + char_count, "\n" ); //char_count += char_length; m_datalen[ count ] = linedirection; m_datalen[ count + 1 ] = i; m_datalen[ count + 2 ] = minY - 2; m_datalen[ count + 3 ] = maxY + 2; count += 4; } } } ///////////////////生成坏线标记文件,by chen G N 2013 - 01 - 16 int CPixMatrix::SaveBadLineMap(const char *fileName) { ////////////////////////////新方法-基于二值图,返回值: -2 坏点文件未载入;-1 坏线写失败;0 无坏线;1有坏线 if(m_BadPixelMap == NULL) { return -2; } long BadPixNum; long BadNum; //////////////////////////标记坏点 //if ( nWidth != m_nWidth && nHeight != m_nHeight ) //{ // unsigned short *m_TempImage = new unsigned short [ m_nWidth * m_nHeight ]; // unsigned short *m_TempImage1 = new unsigned short [ m_nWidth * m_nHeight ]; // nWidth = m_nWidth; // nHeight = m_nHeight; //} memset( m_TempImage, 0, sizeof(unsigned short) * m_nWidth * m_nHeight ); memset( m_TempImage1, 0, sizeof(unsigned short) * m_nWidth * m_nHeight ); for ( int i = 2; i < m_nHeight - 2; i++ ) { m_pBadPixNum = m_BadPixelMap[ i ].bad_pixel_num; if ( m_BadPixelMap[ i ].num_entries > 0 ) { for ( int j = 0; j < m_BadPixelMap[ i ].num_entries; j++ ) { BadPixNum = *m_pBadPixNum++; BadNum = BadPixNum & OFFSET_MASK; if ( BadNum > 1 && BadNum < m_nWidth - 1 ) m_TempImage[ i * m_nWidth + BadNum ] = 65535; } } } /////////////////////按行标记坏线,水平坏线 char *data_out = NULL; long char_count = 0; long char_length; int linedirection; data_out = new char [ 40000 ]; for ( int i = 0; i < m_nHeight; i++ ) { for ( int j = 2; j < m_nWidth - 2; j++ ) { m_TempImage1[ i * m_nWidth + j ] = ( m_TempImage[ i * m_nWidth + j - 2 ] + m_TempImage[ i * m_nWidth + j - 1 ] + m_TempImage[ i * m_nWidth + j ] + m_TempImage[ i * m_nWidth + j + 1 ] + m_TempImage[ i * m_nWidth + j + 2 ] ) / 5; if ( m_TempImage1[ i * m_nWidth + j ] < 40000 ) m_TempImage1[ i * m_nWidth + j ] = 0; else m_TempImage1[ j * m_nWidth + i ] = 65535; } int tempcount = 0; for ( int p = 0; p < m_nWidth; p++ ) { if ( m_TempImage1[ i * m_nWidth + p ] == 65535 ) tempcount++; } int minX = 0; int maxX = 0; if ( tempcount > 500 ) { for ( int k = 0; k < m_nWidth; k++ ) { if ( m_TempImage1[ i * m_nWidth + k ] == 65535 ) { minX = k; break; } } for ( int k1 = m_nWidth - 1; k1 > 0; k1-- ) { if ( m_TempImage1[ i * m_nWidth + k1 ] == 65535 ) { maxX = k1; break; } } linedirection = 0; char_length = sprintf( data_out + char_count, "%d,%d:%d,%d", linedirection, i, minX - 2, maxX + 2 ); char_count += char_length; char_length = sprintf( data_out + char_count, "\n" ); char_count += char_length; } } ////////////////////////////按列标记坏线--竖直坏线 memset( m_TempImage1, 0, sizeof(unsigned short) * m_nWidth * m_nHeight ); for ( int i = 0; i < m_nWidth; i++ ) { for ( int j = 2; j < m_nHeight - 2; j++ ) { m_TempImage1[ j * m_nWidth + i ] = ( m_TempImage[ ( j - 2 ) * m_nWidth + i ] + m_TempImage[ ( j - 1 ) * m_nWidth + i ] + m_TempImage[ j * m_nWidth + i ] + m_TempImage[ ( j + 1 ) * m_nWidth + i ] + m_TempImage[ ( j + 2 ) * m_nWidth + i ] ) / 5; if ( m_TempImage1[ j * m_nWidth + i ] < 40000 ) m_TempImage1[ j * m_nWidth + i ] = 0; else m_TempImage1[ j * m_nWidth + i ] = 65535; } int tempcount = 0; for ( int p = 0; p < m_nHeight; p++ ) { if ( m_TempImage1[ p * m_nWidth + i ] == 65535 ) tempcount++; } int minY = 0; int maxY = 0; if ( tempcount > 500 ) { for ( int k = 0; k < m_nHeight; k++ ) { if ( m_TempImage1[ k * m_nWidth + i ] == 65535 ) { minY = k; break; } } for ( int k1 = m_nHeight - 1; k1 > 0; k1-- ) { if ( m_TempImage1[ k1 * m_nWidth + i ] == 65535 ) { maxY = k1; break; } } linedirection = 1; char_length = sprintf( data_out + char_count, "%d,%d:%d,%d", linedirection, i, minY - 2, maxY + 2 ); char_count += char_length; char_length = sprintf( data_out + char_count, "\n" ); char_count += char_length; } } ///////////////////////写坏线坐标///////////////////////////// if ( char_count == 0 ) { return 0; } else { FILE *fp; fp = fopen(fileName, "wb"); if(m_BadPixelMap == NULL) { return -2; } if (fwrite(data_out,1,char_count,fp)!=char_count) { return -1; } fclose(fp); } if( data_out != NULL ) { delete [] data_out; data_out = NULL; } //if( m_TempImage != NULL ) //{ // delete [] m_TempImage; // m_TempImage = NULL; //} //if( m_TempImage1 != NULL ) //{ // delete [] m_TempImage1; // m_TempImage1 = NULL; //} return 1; } //////////////解决去栅影后的坏线振铃效应,返回-2为异常,返回1为正常去除坏线///////////////////////////////////////// int CPixMatrix::LoadandCorrectBadLine( unsigned short *pImage, int GridDirection ) { //FILE *fp; int line_direction; int line_entries; int startpoint; int endpoint; //int char_count = 0; //int char_length = 0; int count = 0; //char *data_in = NULL; //data_in = new char [MAX_PIX_MAP_LINE]; if( m_datalen == NULL) { return -2; } //fp = fopen(fileName, "rt"); //if(fp == NULL) //{ // return -2; //} // while( (m_datalen + char_count)!= NULL) // { //while( sscanf( m_datalen + char_count, "%d,%d:%d,%d", &line_direction, &line_entries, &startpoint, &endpoint ) == 4 ) //while( (m_datalen[ count ] != -1) && (count < 400) ) while( (m_datalen[ count ] != -1) && (count < m_nLineData) ) //???acoutD?óú×?′ó?μ????êy,zhaoyiru, 2017.05.09 { line_direction = m_datalen[ count ] ; line_entries = m_datalen[ count + 1 ]; startpoint = m_datalen[ count + 2 ]; endpoint = m_datalen[ count + 3 ]; count = count + 4; if( line_direction == 0 && line_entries > 2 && line_entries < m_nHeight - 2 && GridDirection == 2 )//////////////////////去除水平坏线 { int nTGray = 0, nBGray = 0, nGray = 0; int nTDetails = 0, nBDetails = 0, nTAvg = 0, nBAvg = 0; if ( startpoint < m_nWOffset + 2 ) startpoint = m_nWOffset + 2; if ( endpoint > m_nWidth - m_nWOffset - 2 ) endpoint = m_nWidth - m_nWOffset - 2; for ( int i = startpoint; i < endpoint; i++ ) { nTAvg = 0; for ( int j = -2; j < 3; j++ ) { nTAvg += pImage[ ( line_entries - 1 ) * m_nWidth + i + j ]; } nTAvg /= 5; nTDetails = pImage[ ( line_entries - 1 ) * m_nWidth + i ] - nTAvg; nTGray = 0.5 * pImage[ ( line_entries - 2 ) * m_nWidth + i ] + 0.25 * pImage[ ( line_entries - 2 ) * m_nWidth + i - 1 ] + 0.25 * pImage[ ( line_entries - 2 ) * m_nWidth + i + 1 ]; nBGray = 0.5 * pImage[ ( line_entries + 2 ) * m_nWidth + i ] + 0.25 * pImage[ ( line_entries + 2 ) * m_nWidth + i - 1 ] + 0.25 * pImage[ ( line_entries + 2 ) * m_nWidth + i + 1 ]; nGray = 0.75 * nTGray + 0.25 * nBGray; //pImage[ ( line_entries - 1 ) * m_nWidth + i ] = nGray + nTDetails; if ( (nGray + nTDetails) < 0 ) pImage[ ( line_entries - 1 ) * m_nWidth + i ] = 0; else if ( (nGray + nTDetails) > 65535 ) pImage[ ( line_entries - 1 ) * m_nWidth + i ] = 65535; else pImage[ ( line_entries - 1 ) * m_nWidth + i ] = nGray + nTDetails; } for ( int i = startpoint; i < endpoint; i++ ) { nBAvg = 0; for ( int j = -2; j < 3; j++ ) { nBAvg += pImage[ ( line_entries + 1 ) * m_nWidth + i + j ]; } nBAvg /= 5; nBDetails = pImage[ ( line_entries + 1 ) * m_nWidth + i ] - nBAvg; nTGray = 0.5 * pImage[ ( line_entries - 2 ) * m_nWidth + i ] + 0.25 * pImage[ ( line_entries - 2 ) * m_nWidth + i - 1 ] + 0.25 * pImage[ ( line_entries - 2 ) * m_nWidth + i + 1 ]; nBGray = 0.5 * pImage[ ( line_entries + 2 ) * m_nWidth + i ] + 0.25 * pImage[ ( line_entries + 2 ) * m_nWidth + i - 1 ] + 0.25 * pImage[ ( line_entries + 2 ) * m_nWidth + i + 1 ]; nGray = 0.25 * nTGray + 0.75 * nBGray; //pImage[ ( line_entries - 1 ) * m_nWidth + i ] = nGray + nBDetails; if ( (nGray + nBDetails) < 0 ) pImage[ ( line_entries + 1 ) * m_nWidth + i ] = 0; else if ( (nGray + nBDetails) > 65535 ) pImage[ ( line_entries + 1 ) * m_nWidth + i ] = 65535; else pImage[ ( line_entries + 1 ) * m_nWidth + i ] = nGray + nBDetails; } for ( int i = startpoint; i < endpoint; i++ ) { pImage[ ( line_entries ) * m_nWidth + i ] = 0.25 * pImage[ ( line_entries + 1 ) * m_nWidth + i ] + 0.125 * pImage[ ( line_entries + 1 ) * m_nWidth + i - 1 ] + 0.125 * pImage[ ( line_entries + 1 ) * m_nWidth + i + 1 ] + 0.25 * pImage[ ( line_entries - 1 ) * m_nWidth + i ] + 0.125 * pImage[ ( line_entries - 1 ) * m_nWidth + i - 1 ] + 0.125 * pImage[ ( line_entries - 1 ) * m_nWidth + i + 1 ]; } } if( line_direction == 1 && line_entries > 2 && line_entries < m_nWidth - 2 && GridDirection == 1 )//////////////////////去除竖直坏线 { int nLGray = 0, nRGray = 0, nGray = 0; int nLDetails = 0, nRDetails = 0, nLAvg = 0, nRAvg = 0; if ( startpoint < m_nHOffset + 2 ) startpoint = m_nHOffset + 2; if ( endpoint > m_nHeight - m_nHOffset - 2 ) endpoint = m_nHeight - m_nHOffset - 2; for ( int i = startpoint; i < endpoint; i++ ) { nLAvg = 0; for ( int j = -2; j < 3; j++ ) { nLAvg += pImage[ ( i + j ) * m_nWidth + line_entries - 1 ]; } nLAvg /= 5; nLDetails = pImage[ i * m_nWidth + line_entries - 1 ] - nLAvg; nLGray = 0.5 * pImage[ i * m_nWidth + line_entries - 2 ] + 0.25 * pImage[ ( i - 1 ) * m_nWidth + line_entries - 2 ] + 0.25 * pImage[ ( i + 1 ) * m_nWidth + line_entries - 2 ]; nRGray = 0.5 * pImage[ i * m_nWidth + line_entries + 2 ] + 0.25 * pImage[ ( i - 1 ) * m_nWidth + line_entries + 2 ] + 0.25 * pImage[ ( i + 1 ) * m_nWidth + line_entries + 2 ]; nGray = 0.75 * nLGray + 0.25 * nRGray; //pImage[ i * m_nWidth + line_entries - 1 ] = nGray + nLDetails; if ( (nGray + nLDetails) < 0 ) pImage[ i * m_nWidth + line_entries - 1 ] = 0; else if ( (nGray + nLDetails) > 65535 ) pImage[ i * m_nWidth + line_entries - 1 ] = 65535; else pImage[ i * m_nWidth + line_entries - 1 ] = nGray + nLDetails; } for ( int i = startpoint; i < endpoint; i++ ) { nRAvg = 0; for ( int j = -2; j < 3; j++ ) { nRAvg += pImage[ ( i + j ) * m_nWidth + line_entries + 1 ]; } nRAvg /= 5; nRDetails = pImage[ i * m_nWidth + line_entries + 1 ] - nRAvg; nLGray = 0.5 * pImage[ i * m_nWidth + line_entries - 2 ] + 0.25 * pImage[ ( i - 1 ) * m_nWidth + line_entries - 2 ] + 0.25 * pImage[ ( i + 1 ) * m_nWidth + line_entries - 2 ]; nRGray = 0.5 * pImage[ i * m_nWidth + line_entries + 2 ] + 0.25 * pImage[ ( i - 1 ) * m_nWidth + line_entries + 2 ] + 0.25 * pImage[ ( i + 1 ) * m_nWidth + line_entries + 2 ]; nGray = 0.75 * nRGray + 0.25 * nLGray; //pImage[ i * m_nWidth + line_entries - 1 ] = nGray + nRDetails; if ( (nGray + nRDetails) < 0 ) pImage[ i * m_nWidth + line_entries + 1 ] = 0; else if ( (nGray + nRDetails) > 65535 ) pImage[ i * m_nWidth + line_entries + 1 ] = 65535; else pImage[ i * m_nWidth + line_entries + 1 ] = nGray + nRDetails; } for ( int i = startpoint; i < endpoint; i++ ) { pImage[ i * m_nWidth + line_entries ] = 0.25 * pImage[ i * m_nWidth + line_entries + 1 ] + 0.125 * pImage[ ( i - 1 ) * m_nWidth + line_entries + 1 ] + 0.125 * pImage[ ( i + 1 ) * m_nWidth + line_entries + 1 ] + 0.25 * pImage[ i * m_nWidth + line_entries - 1 ] + 0.125 * pImage[ ( i - 1 ) * m_nWidth + line_entries - 1 ] + 0.125 * pImage[ ( i + 1 ) * m_nWidth + line_entries - 1 ]; } } //char_count += 4; //char_length = sprintf( m_datalen + char_count, "\n" ); //char_count += char_length; } // } //if(fp != NULL) //{ // fclose(fp); //} //if(data_in != NULL) //{ // delete [] data_in; //} return 1; } bool CPixMatrix::AutoBadPixelMap(WORD *wImage) { char * m_charBadPixMap; char * m_charLinePixMap; m_charLinePixMap = new char [MAX_PIX_MAP_LINE]; m_charBadPixMap = new char [MAXI_BADPIX_COUNT]; BYTE *wImageWB = new BYTE [m_nWidth* m_nHeight]; int i,j; // for loop DWORD Hist[16384]; DWORD count = 0; DWORD tempsum = 0; WORD lowvalue, highvalue; lowvalue = highvalue = 0; bool state = true; for(i = 0; i< 16384; i++) { Hist[i] = 0; } //统计直方图 for(i = m_nHeight/3; i count) break; } lowvalue = max(i-1500, 100); tempsum = 0; for(i = m_nPixelMax ; i>0; i--) { tempsum += Hist[i]; if (tempsum> count) break; } highvalue = min(i+1500, m_nPixelMax); for(i = 0; ilowvalue)&&(*(wImage+i*m_nWidth+j)=0; i--) { if(!((*(wImageWB+m_nWidth*(m_nHeight-i-1)+m_nWidth/3)==0)&&(*(wImageWB+m_nWidth*(m_nHeight-i-1)+2*m_nWidth/3)==0))) { y2 = i; break; } } for(j = 0; j=0; j--) { if(!((*(wImageWB+m_nWidth*m_nHeight/3+j)==0)&&(*(wImageWB+2*m_nWidth*m_nHeight/3+j)==0))) { x2 = j; break; } } */ long char_count; long char_length; long nPixcount; nPixcount=char_count = char_length = 0; // 每列 for(i = 0; i(MAXI_BADPIX_COUNT-MAX_PIX_MAP_LINE)){ state = false; // AfxMessageBox("Too Many bad point, maybe bad method to expose!"); //gfun_LogError("Too Many bad point, maybe bad method to expose!"); break; } char_count += sprintf(m_charBadPixMap+char_count,"%d,%d:",i,nPixcount); memcpy(m_charBadPixMap+char_count,m_charLinePixMap,char_length); char_count += char_length; char_count += sprintf(m_charBadPixMap+char_count,"\n"); } if(state) { for(i = y2+1; ithreshold2)) wImageWB[i] = 0; else wImageWB[i] = 255; } //查找空边 int x1,x2,y1,y2; x1 = m_nWOffset; x2 = m_nWidth-m_nWOffset; y1 = m_nHOffset; y2 = m_nHeight-m_nHOffset; long char_count; long char_length; long nPixcount; nPixcount=char_count = char_length = 0; // 每列 for(i = 0; i(MAXI_BADPIX_COUNT-MAX_PIX_MAP_LINE)){ state = false; // AfxMessageBox("Too Many bad point, maybe bad method to expose!"); //gfun_LogError("Too Many bad point, maybe bad method to expose!"); break; } char_count += sprintf(m_charBadPixMap+char_count,"%d,%d:",i,nPixcount); memcpy(m_charBadPixMap+char_count,m_charLinePixMap,char_length); char_count += char_length; char_count += sprintf(m_charBadPixMap+char_count,"\n"); } if(state) { for(i = y2+1; i(MAXI_BADPIX_COUNT-MAX_PIX_MAP_LINE)){ state = false; // AfxMessageBox("Too Many bad point, maybe bad method to expose!"); //gfun_LogError("Too Many bad point, maybe bad method to expose!"); break; } char_count += sprintf(m_charBadPixMap+char_count,"%d,%d:",i,nPixcount); memcpy(m_charBadPixMap+char_count,m_charLinePixMap,char_length); char_count += char_length; char_count += sprintf(m_charBadPixMap+char_count,"\n"); } if(state) { for(i = y2; inextline; delete ptemp; } } void CPixMatrix::FreeBadNewPixelMap() { if(m_BadNewPixelMap != NULL) { for(int i = 0 ; i < m_nHeight ; ++i) { if(m_BadNewPixelMap[i].bad_pixel_num != NULL) { delete [] m_BadNewPixelMap[i].bad_pixel_num; m_BadNewPixelMap[i].bad_pixel_num = NULL; } } delete [] m_BadNewPixelMap; m_BadNewPixelMap = NULL; } } bool CPixMatrix::CombineBadPixelMap() { long line; long bad_pix_num; long bad_pix_numcount; long bad_new_pix_num; long bad_new_pix_numcount; long bad_temp_pix_num; // long bad_pix; // long bad_new_pix; long *p_bad_pix_num; long *p_bad_new_pix_num; long *p_bad_temp_pix; if (m_BadNewPixelMap == NULL) return TRUE; if (m_BadPixelMap == NULL) { m_BadPixelMap = m_BadNewPixelMap; m_BadNewPixelMap = NULL; return TRUE; } for(line = 0 ; line < m_nHeight ; ++line) { //逐行合并 bad_pix_num = m_BadPixelMap[line].num_entries; bad_new_pix_num = m_BadNewPixelMap[line].num_entries; p_bad_pix_num = m_BadPixelMap[line].bad_pixel_num; p_bad_new_pix_num = m_BadNewPixelMap[line].bad_pixel_num; bad_temp_pix_num = bad_pix_numcount = bad_new_pix_numcount = 0; if(bad_new_pix_num==0) continue; p_bad_temp_pix = new long [(bad_pix_num+bad_new_pix_num+1)*sizeof(long)]; memset( p_bad_temp_pix, 0, (bad_pix_num+bad_new_pix_num+1) * sizeof(long)); while (!((bad_pix_numcount>=bad_pix_num)&&(bad_new_pix_numcount>=bad_new_pix_num))) { if(bad_pix_numcount==bad_pix_num) { for(;bad_new_pix_numcount (*(p_bad_pix_num+bad_pix_numcount)& OFFSET_MASK)) { *(p_bad_temp_pix+bad_temp_pix_num) = *(p_bad_pix_num+bad_pix_numcount); bad_temp_pix_num++; bad_pix_numcount++; } else if((*(p_bad_new_pix_num+bad_new_pix_numcount)& OFFSET_MASK)< (*(p_bad_pix_num+bad_pix_numcount)& OFFSET_MASK)) { *(p_bad_temp_pix+bad_temp_pix_num) = *(p_bad_new_pix_num+bad_new_pix_numcount); bad_temp_pix_num++; bad_new_pix_numcount++; } else { *(p_bad_temp_pix+bad_temp_pix_num) = *(p_bad_pix_num+bad_pix_numcount); bad_temp_pix_num++; bad_pix_numcount++; bad_new_pix_numcount++; } } delete [] m_BadPixelMap[line].bad_pixel_num; m_BadPixelMap[line].bad_pixel_num = new long [(bad_temp_pix_num+1)*sizeof(long)]; m_BadPixelMap[line].num_entries = bad_temp_pix_num; memcpy(m_BadPixelMap[line].bad_pixel_num,p_bad_temp_pix,(bad_temp_pix_num+1)*sizeof(long)); delete [] p_bad_temp_pix; } FreeBadNewPixelMap(); return TRUE; } bool CPixMatrix::AutoBadPixelFixed(WORD *wImage, int threshold) { DWORD Temp,Sum; //指向DIB图像中的数据; WORD* pDataByte; //差值,与阈值比较 int idelta; // int count; // WORD sourcetemp[9]; int i,j,x,y,k;//for loop for (j = m_nHOffset+2; j < m_nHeight-m_nHOffset; j++) { Temp = (*(wImage + j*m_nWidth - 1) + *(wImage + j*m_nWidth) + *(wImage + j*m_nWidth + 1) + *(wImage + (j-1)*m_nWidth - 1) + *(wImage + (j-1)*m_nWidth) + *(wImage + (j-1)*m_nWidth + 1)+ *(wImage + (j+1)*m_nWidth - 1) + *(wImage + (j+1)*m_nWidth) + *(wImage + (j+1)*m_nWidth + 1))/9; for (i = m_nWOffset+2; i < m_nWidth-m_nHOffset ; i++) { //如果差值小于阈值,则不改变此点 pDataByte = wImage + j * m_nWidth + i; idelta = *pDataByte - Temp; if (idelta<0) idelta = -1*idelta; if (idelta > threshold) { //如果差值大于阈值,则在邻近区域3x3找到所有满足阈值条件的点,取均值 Sum = 0; k = 0; for (y = j - 1; y<= j+1; y++) { pDataByte = (unsigned short*)(wImage + y * m_nWidth + i - 1); for(x = i - 1; x <= i+1; x++) { idelta = *pDataByte - Temp; if (idelta<0) idelta = -1*idelta; if (idelta > threshold) break; Sum += *pDataByte; pDataByte++; k++; } } if (k>3) *(wImage + j * m_nWidth + i) = (WORD)Sum/k; } Temp = *(wImage + j * m_nWidth + i); } } return TRUE; } bool CPixMatrix::LoadLineMap( const char *fileName ) { FILE *fp; long *line_direction = new long; long *line_entries = new long; long *startpoint = new long; long *endpoint = new long; char *data_in = NULL; data_in = new char [MAX_PIX_MAP_LINE]; LINE_MAP * m_xLineMapCur = NULL; LINE_MAP * m_yLineMapCur = NULL; if(data_in == NULL) { return FALSE; } fp = fopen(fileName, "rb"); if(fp == NULL) { return FALSE; } FreeLineMap(m_xLineMap); m_xLineMap = NULL; FreeLineMap(m_yLineMap); m_yLineMap = NULL; while(fgets(data_in, MAX_PIX_MAP_LINE, fp) != NULL) { if(sscanf(data_in, "%d,%d:%d,%d", line_direction, line_entries, startpoint, endpoint) == 4) { // line_direction = 0;line_entries=359, startpoint=45, endpoint=2700; if(*line_direction==0) { m_xLineMapCur = new LINE_MAP; m_xLineMapCur->nextline = m_xLineMap; m_xLineMapCur->lLine = FALSE; m_xLineMapCur->rLine = FALSE; m_xLineMapCur->line_entries = (WORD)*line_entries; m_xLineMapCur->startpoint = (WORD)*startpoint; m_xLineMapCur->endpoint = (WORD)*endpoint; m_xLineMap = m_xLineMapCur; } else { m_yLineMapCur = new LINE_MAP; m_yLineMapCur->nextline = m_yLineMap; m_yLineMapCur->lLine = FALSE; m_yLineMapCur->rLine = FALSE; m_yLineMapCur->line_entries = (WORD)*line_entries; m_yLineMapCur->startpoint = (WORD)*startpoint; m_yLineMapCur->endpoint = (WORD)*endpoint; m_yLineMap = m_yLineMapCur; } } } MarkAdjacentLine(m_xLineMap); MarkAdjacentLine(m_yLineMap); if(fp != NULL) { fclose(fp); } if(data_in != NULL) { delete [] data_in; } if(m_xLineMapCur){ FreeLineMap(m_xLineMapCur); } delete line_direction; delete line_entries; delete startpoint; delete endpoint; return TRUE; } void CPixMatrix::CorrectDBadLines(WORD *image) { LINE_MAP2 * m_DLineMapCur = m_doubleLineMap; while(m_DLineMapCur) { if(m_DLineMapCur->nLineType == 0) { CorrectDXLines(image, m_DLineMapCur->line_entries, m_DLineMapCur->startpoint, m_DLineMapCur->endpoint); } else { CorrectDYLines(image, m_DLineMapCur->line_entries, m_DLineMapCur->startpoint, m_DLineMapCur->endpoint); } m_DLineMapCur = m_DLineMapCur->nextline; } } void CPixMatrix::SwitchDBadLines(WORD *image) { LINE_MAP2 * m_DLineMapCur = m_doubleLineMap; int specX = CalSpecX(image); int specY = CalSpecY(image); while (m_DLineMapCur) { if (m_DLineMapCur->nLineType == 0) { SwitchDXLines(image, m_DLineMapCur->line_entries, m_DLineMapCur->startpoint, m_DLineMapCur->endpoint, specX); } else { SwitchDYLines(image, m_DLineMapCur->line_entries, m_DLineMapCur->startpoint, m_DLineMapCur->endpoint, specY); } m_DLineMapCur = m_DLineMapCur->nextline; } } // modified by shihaozhe on 2019-4-18 //below is old version /*void CPixMatrix::CorrectDXLines(WORD *image, int nentry, int nstart, int nend) { int nA,nB,nC, nA1, nA2, nB1, nB2, nC1, nC2; int nMIN;//, MID, MAX; for(int i = nstart; i= Flag2Votes) spec = 2; else spec = 3; return spec; } int CPixMatrix::CalSpecY(WORD* image) { int spec = 2; int Flag1Votes = 0; int Flag2Votes = 0; for (int i = 3; i < (m_nWidth - 4); i = i + 100) { for (int j = 0; j < m_nHeight; j++) { float Flag1ResLine1 = (float(image[j * m_nWidth + (i - 2)]) / 2 + float(image[j* m_nWidth + (i + 2)]) / 2); float Flag1ResLine2 = (float(image[j * m_nWidth + (i - 1)]) / 2 + float(image[j * m_nWidth + (i + 3)]) / 2); float Flag2ResLine1 = (float(image[j * m_nWidth + (i - 3)]) / 2 + float(image[j * m_nWidth + (i + 3)]) / 2); float Flag2ResLine2 = (float(image[j * m_nWidth + (i - 2)]) / 2 + float(image[j * m_nWidth + (i + 4)]) / 2); float Flag1Score = abs(Flag1ResLine1 - float(image[j * m_nWidth + i])) + abs(Flag1ResLine2 - float(image[j * m_nWidth + (i + 1)])); float Flag2Score = abs(Flag2ResLine1 - float(image[j * m_nWidth + i])) + abs(Flag2ResLine2 - float(image[j * m_nWidth + (i + 1)])); if (Flag1Score < Flag2Score) Flag1Votes++; else Flag2Votes++; } } if (Flag1Votes >= Flag2Votes) spec = 2; else spec = 3; return spec; } void CPixMatrix::SwitchDXLines(WORD* image, int nentry, int nstart, int nend, int spec) { if (nentry < 1 || nentry >= m_nHeight) return; if ((nentry - 1 - spec) >= 0 && (nentry + spec) < m_nHeight) { for (int i = nstart; i < nend; i++) { image[(nentry - 1) * m_nWidth + i] = WORD((float(image[(nentry - 1 - spec) * m_nWidth + i]) + float(image[(nentry - 1 + spec) * m_nWidth + i])) / 2); image[nentry * m_nWidth + i] = WORD((float(image[(nentry - spec) * m_nWidth + i]) + float(image[(nentry + spec) * m_nWidth + i])) / 2); } } else if ((nentry - 1 - spec) < 0) { for (int i = nstart; i < nend; i++) { image[(nentry - 1) * m_nWidth + i] = image[(nentry - 1 + spec) * m_nWidth + i]; image[nentry * m_nWidth + i] = image[(nentry + spec) * m_nWidth + i]; } } else { for (int i = nstart; i < nend; i++) { image[(nentry - 1) * m_nWidth + i] = image[(nentry - 1 - spec) * m_nWidth + i]; image[nentry * m_nWidth + i] = image[(nentry - spec) * m_nWidth + i]; } } } void CPixMatrix::SwitchDYLines(WORD* image, int nentry, int nstart, int nend, int spec) { if (nentry < 1 || nentry >= m_nWidth) return; if ((nentry - 1 - spec) >= 0 && (nentry + spec) < m_nWidth) { for (int i = nstart; i < nend; i++) { image[i * m_nWidth + (nentry - 1)] = WORD((float(image[i * m_nWidth + (nentry - 1 - spec)]) + float(image[i * m_nWidth + (nentry - 1 + spec)])) / 2); image[i * m_nWidth + nentry] = WORD((float(image[i * m_nWidth + (nentry - spec)]) + float(image[i * m_nWidth + (nentry + spec)])) / 2); } } else if ((nentry - 1 - spec) < 0) { for (int i = nstart; i < nend; i++) { image[i * m_nWidth + (nentry - 1)] = image[i * m_nWidth + (nentry - 1 + spec)]; image[i * m_nWidth + nentry] = image[i * m_nWidth + (nentry + spec)]; } } else { for (int i = nstart; i < nend; i++) { image[i * m_nWidth + (nentry - 1)] = image[i * m_nWidth + (nentry - 1 - spec)]; image[i * m_nWidth + nentry] = image[i * m_nWidth + (nentry - spec)]; } } } void CPixMatrix::CorrectDXLines(WORD *image, int nentry, int nstart, int nend) { float w0[20][10] = { { -1.80551376e-01 , 1.48339527e-01 , 1.93434153e-01 ,-1.69102470e-01, -8.30293637e-02 , 4.68743068e-11 ,1.07092565e-01 , 4.90719458e-02, -1.76974159e-06 ,-2.34796443e-01 }, { 2.26791936e-01 ,-4.42808635e-02 ,-1.96939813e-03 , 1.14001209e-01, 6.47560641e-01 , 5.78895742e-11 ,-4.89402386e-02 ,-4.71011428e-02, 1.41082019e-06 ,4.77452935e-01 }, { 7.13725661e-01, -4.36174689e-01 ,1.00634693e-01 ,-2.00562230e-02, 4.35445448e-01 , 4.63354817e-12 , 2.24216928e-01, -6.99454931e-02, -2.63495911e-06 , 3.18166017e-01 }, { -1.64505637e-01, 6.80188531e-03 , 2.86472226e-01 ,-4.37072848e-01, 1.32676203e-03 ,-1.86652083e-11 , 5.94614663e-02 ,-2.56715695e-01, 3.52631615e-08 , 1.19374415e-02 }, { 1.92242685e-01 , 1.81255810e-02 ,-3.13366263e-01 , 1.65171353e-01, 6.37306352e-02 ,-8.55124219e-11 , 2.06302921e-03 , 7.13230627e-02, -8.22837481e-08 , 4.43748465e-04 }, { 2.56683926e-02 ,-1.32064094e-01 ,5.92931576e-01 ,-3.93658658e-01, 1.89241730e-01 ,-1.02160955e-10 ,-2.60349051e-01, 6.00632605e-02, -1.08522973e-06 , 1.38723903e-02 }, { 2.01019043e-01 , 4.60498596e-01 , 5.17829841e-01 ,-7.58273701e-01, -1.86647317e-02 ,-1.76434531e-11, -6.46477206e-01, 4.13885018e-01, -1.16803458e-06, -4.68910295e-01 }, { 8.62645998e-01 , 9.68335169e-01 , 8.94262963e-02 , 1.74861574e-01, -1.85454720e-01 ,-3.19849587e-11 , 5.96511029e-01 ,6.05654463e-01, -7.56176036e-07, -5.07831177e-01 }, { -8.71116572e-02, 3.66096894e-01 ,-6.28023440e-01 , 6.91073259e-01, 3.01648578e-01 ,-1.15338717e-10 ,3.58207881e-01 , 6.94645261e-01, -5.48317706e-06 ,-5.13752419e-01 }, { 2.82701627e-01 ,-1.52676216e-01 ,-1.74173102e-01 , 1.68326554e-01, -2.20833287e-01, -1.17141445e-10 ,-2.30629014e-01 , 5.09502973e-02, 1.03628056e-05 , 5.17466666e-02 }, { -2.93915459e-01, 2.59599255e-01, -1.57063692e-01 ,2.47658474e-01, 2.44114791e-01 ,-4.60543803e-11 , 1.60940275e-01, 2.99402289e-01, -5.21160106e-07 ,-6.60931206e-02 }, { -2.18481332e-01, -3.65660965e-02 ,-2.76270937e-01 , 6.37817927e-01, -2.25210248e-01 ,-2.57545543e-11 , 5.04407490e-01 , 3.25644418e-01, -1.67397865e-06 ,-3.38918731e-01 }, { 4.30656416e-01 ,-6.05850820e-01 , 3.56411868e-01 , 1.39871104e-01, 1.61133433e-02, 1.95278541e-11, 4.25782008e-01 ,9.79111337e-01, -9.56787789e-07, -3.11803801e-01 }, { -2.36239573e-01 ,-1.73015706e-01 , 3.71253420e-01 ,-4.43126520e-01, -6.16987099e-01, -3.47112370e-11 ,-9.48308722e-02 , 2.35392910e-01, 3.90978755e-07 ,-5.30585275e-01 }, { -9.21914745e-03 , 2.10569685e-01 , 5.86744516e-01, -3.29272382e-01, 6.87882591e-02 ,-5.60479430e-11, -1.31813225e-01 ,-9.01748595e-02, 1.48535772e-06 ,7.75831897e-02 }, { -3.87850229e-02 , 2.12077616e-02 , 3.81875744e-02 ,1.12848455e-01, 1.83825444e-01, -1.18965572e-10 ,1.27163810e-01, 9.96867991e-02, 1.84582238e-06 ,7.19917185e-02 }, { -5.18885615e-02 ,-1.74264405e-01 ,2.27000308e-01, -4.29314728e-01, -1.17003563e-01, -2.81658523e-11 , 1.17201003e-01 ,-3.07566778e-01, -2.01403760e-06 ,-9.42299766e-02 }, { 4.90024471e-01 , 3.71047916e-02 , 1.01772677e-01, 9.51157739e-02, -1.71601670e-01 ,9.38432195e-11 , 6.24270660e-01, -4.71965703e-01, -3.31362503e-07 , 4.29190240e-01 }, { 7.14228024e-02 ,-5.00837424e-02 , 1.47659839e-01 , 5.17815234e-02, 3.52253877e-01 ,4.90728233e-11 , 2.23559528e-01 ,-2.22637845e-01, -1.25922349e-06 , 2.04710832e-01 }, { -1.36544728e-01 ,-1.49882902e-03 , 1.16554738e-01 ,-1.07862765e-01, 9.45728675e-02 , 2.68435951e-11 ,-2.67820297e-02, 1.89775976e-01, -2.41099251e-06, -1.34862793e-01 } }; float w1[10][10] = { { -0.23780609 ,-0.20482226 , 0.41957468, 0.40999775, 0.38139455 ,0.49962715, 0.08417365 , 0.29976534 ,-0.08972183 ,-0.0574983 }, { 0.07750195 ,-0.75130445 ,-0.06468749 ,-0.09033038 ,-0.18993429 ,0.82029747, -0.61669163 , 0.01430632 , 0.07597411, 0.27505365 }, { 0.49405426, 0.01242133 ,0.25904818 ,0.41172925 ,0.07578099 ,0.06032476, 0.46222851, 0.06112816, 0.23961187, 0.11556222 }, { 1.03532351 , 0.00237677 ,-1.41761159 , 0.2577502 ,-0.29667514 ,-0.22258016, 1.01807614, 0.47470323 , 0.64205134 , 1.17553243 }, { -0.54341226 , 0.05698822 ,-0.63832775 ,-0.3224985, -0.08834335 ,-0.20154572, 0.33619324 , 0.53621269 ,-0.08154711 , 0.10801987 }, { -1.43359900e-10, -2.19706358e-11 ,-7.62980145e-11 , 3.80564307e-11, 1.43483774e-10 ,1.43472783e-10 ,-7.14971534e-11 ,-4.57497718e-11, -7.01573521e-11 , 1.53484506e-10 }, { -0.27199681, -0.06586821 , 0.06227236 ,0.50916823 ,0.12266234 , 0.25784538, 0.21391334 ,-0.04650493 ,-0.21507827 ,-0.81284655 }, { 0.07606676, 0.13142832 ,-0.53617744 , 0.42486831 , 0.89048667 , 0.3048935, -0.71382582, -0.61000717 ,0.2688673 , 0.47569795 }, { 1.52424197e-07 , 6.22315298e-08 - 6.52738940e-11 ,-8.68034280e-07, -5.31746214e-07 ,-1.78368165e-07 ,-2.11015294e-08, -1.52950988e-06, -3.42529575e-11, 2.35200781e-07 }, { -0.9658597 ,-0.68771416, -0.14909613, -0.27739111 , 0.38529542, 0.14808103, -0.24781566 ,-0.52709518 ,0.07968214 ,-1.09388288 } }; float w2[10][4] = { { -5.53134378e-01, -5.05213046e-02, 1.17674467e+00, 1.71470806e-10 }, { 4.66713499e-01, 4.28506910e-01, -9.50886462e-02, 1.16200494e-10 }, { 2.57455827e-01, -3.01318414e-02, -4.42330819e-01, 1.27572777e-10 }, { 4.97257812e-02 ,1.68243289e-01 ,4.46669062e-01 ,2.76339875e-11 }, { -2.00255754e-01, 3.68610428e-01 , 2.01173992e-01, -6.76783395e-11 }, { -6.26138176e-02, -5.74267944e-01, 3.32356077e-01 ,-6.16432376e-12 }, { 5.33413965e-02, -5.74108504e-02 ,-7.05800150e-01 ,-1.82851013e-10 }, { -1.06458783e+00 ,-1.52935556e-01 ,-1.45886105e+00 ,-1.01166814e-10 }, { 2.78628319e-08, 2.87125783e-01 ,-1.52646659e+00 ,-1.70692624e-10 }, { -2.66851493e-01 ,-4.95637535e-02 , 7.59249111e-01 ,-6.39687400e-11 } }; float w3[4][2] = { { 0.34269875 ,0.28160403 },{ -0.2269393 , 0.46291535 },{ 0.35116205 ,0.32428314 },{ 4.44950996e-11 ,-1.64150986e-10 } }; float b0[10] = { -0.16749457 , 0.51837033 , 0.38030122 , 0.2287536 , 0.31281455 ,-0.31270079, -0.23713096, -0.27459556 ,-0.0780897 , 0.78092204 }; float b1[10] = { -0.19847084 , 0.51427174 ,0.16520637 , 0.02815113 ,0.14546747 ,-0.33054209, -0.22630977 ,-0.21777402 ,-0.68041806 ,-0.51254995 }; float b2[4] = { 0.10842243 , 0.55213982 ,-0.18210444, -0.43683546 }; float b3[2] = { 0.22007598, -0.15169636 }; if (nentry < 3 || nentry >(m_nHeight - 3)) return; for (int i = nstart; i(m_nWidth - 3)) { image[nentry * m_nWidth + i] = image[(nentry + 1) * m_nWidth + i]; image[(nentry - 1) * m_nWidth + i] = image[(nentry - 2) * m_nWidth + i]; } else { float x0[1][20]; int count = 0; float maxP = 0; float minP = 1e9; for (int k = -3; k <= 2; k++) { if (k == -1 || k == 0) continue; for (int l = -2; l <= 2; l++) { *((float*)x0 + count) = float(image[(nentry + k) * m_nWidth + (i + l)]); count++; maxP = max(maxP, float(image[(nentry + k) * m_nWidth + (i + l)])); minP = min(minP, float(image[(nentry + k) * m_nWidth + (i + l)])); } } if ((maxP - minP) > 2560) { maxP = min(maxP + 256, 65535.0f); minP = max(minP - 256, 0.0f); } if((maxP - minP) < 1)maxP = minP + 1; for (int k = 0; k < 20; k++) { *((float*)x0 + k) = (*((float*)x0 + k) - minP) / (maxP - minP); } float z1[1][20]; float x1[1][20]; float z2[1][10]; float x2[1][10]; float z3[1][5]; float x3[1][5]; float z4[1][2]; float y[1][2]; matMul((float**)w0, 20, 10, (float**)x0, 1, 20, b0, (float**)z1); relu((float**)z1, 1, 10, (float**)x1); matMul((float**)w1, 10, 10, (float**)x1, 1, 10, b1, (float**)z2); relu((float**)z2, 1, 10, (float**)x2); matMul((float**)w2, 10, 4, (float**)x2, 1, 10, b2, (float**)z3); relu((float**)z3, 1, 4, (float**)x3); matMul((float**)w3, 4, 2, (float**)x3, 1, 4, b3, (float**)z4); relu((float**)z4, 1, 2, (float**)y); float predict1 = max(min(*((float*)y) * (maxP - minP) + minP, 65535.0f), 0.0f); float predict2 = max(min(*((float*)y + 1) * (maxP - minP) + minP, 65535.0f), 0.0f); float flag1line1 = float(image[(nentry - 3) * m_nWidth + i]) / 2 + float(image[(nentry + 1) * m_nWidth + i]) / 2; float flag1line2 = float(image[(nentry - 2) * m_nWidth + i]) / 2 + float(image[(nentry + 2) * m_nWidth + i]) / 2; float flag1score = abs(flag1line1 - predict1) + abs(flag1line2 - predict2); if (flag1score < 30) { image[(nentry - 1) * m_nWidth + i] = WORD(max(min(flag1line1, 65535.0f), 0.0f)); image[nentry * m_nWidth + i] = WORD(max(min(flag1line2, 65535.0f), 0.0f)); } else { image[(nentry - 1) * m_nWidth + i] = WORD(predict1); image[nentry * m_nWidth + i] = WORD(predict2); } } } } void CPixMatrix::CorrectDYLines(WORD *image, int nentry, int nstart, int nend) { float w0[20][10] = { { -1.80551376e-01 , 1.48339527e-01 , 1.93434153e-01 ,-1.69102470e-01, -8.30293637e-02 , 4.68743068e-11 ,1.07092565e-01 , 4.90719458e-02, -1.76974159e-06 ,-2.34796443e-01 }, { 2.26791936e-01 ,-4.42808635e-02 ,-1.96939813e-03 , 1.14001209e-01, 6.47560641e-01 , 5.78895742e-11 ,-4.89402386e-02 ,-4.71011428e-02, 1.41082019e-06 ,4.77452935e-01 }, { 7.13725661e-01, -4.36174689e-01 ,1.00634693e-01 ,-2.00562230e-02, 4.35445448e-01 , 4.63354817e-12 , 2.24216928e-01, -6.99454931e-02, -2.63495911e-06 , 3.18166017e-01 }, { -1.64505637e-01, 6.80188531e-03 , 2.86472226e-01 ,-4.37072848e-01, 1.32676203e-03 ,-1.86652083e-11 , 5.94614663e-02 ,-2.56715695e-01, 3.52631615e-08 , 1.19374415e-02 }, { 1.92242685e-01 , 1.81255810e-02 ,-3.13366263e-01 , 1.65171353e-01, 6.37306352e-02 ,-8.55124219e-11 , 2.06302921e-03 , 7.13230627e-02, -8.22837481e-08 , 4.43748465e-04 }, { 2.56683926e-02 ,-1.32064094e-01 ,5.92931576e-01 ,-3.93658658e-01, 1.89241730e-01 ,-1.02160955e-10 ,-2.60349051e-01, 6.00632605e-02, -1.08522973e-06 , 1.38723903e-02 }, { 2.01019043e-01 , 4.60498596e-01 , 5.17829841e-01 ,-7.58273701e-01, -1.86647317e-02 ,-1.76434531e-11, -6.46477206e-01, 4.13885018e-01, -1.16803458e-06, -4.68910295e-01 }, { 8.62645998e-01 , 9.68335169e-01 , 8.94262963e-02 , 1.74861574e-01, -1.85454720e-01 ,-3.19849587e-11 , 5.96511029e-01 ,6.05654463e-01, -7.56176036e-07, -5.07831177e-01 }, { -8.71116572e-02, 3.66096894e-01 ,-6.28023440e-01 , 6.91073259e-01, 3.01648578e-01 ,-1.15338717e-10 ,3.58207881e-01 , 6.94645261e-01, -5.48317706e-06 ,-5.13752419e-01 }, { 2.82701627e-01 ,-1.52676216e-01 ,-1.74173102e-01 , 1.68326554e-01, -2.20833287e-01, -1.17141445e-10 ,-2.30629014e-01 , 5.09502973e-02, 1.03628056e-05 , 5.17466666e-02 }, { -2.93915459e-01, 2.59599255e-01, -1.57063692e-01 ,2.47658474e-01, 2.44114791e-01 ,-4.60543803e-11 , 1.60940275e-01, 2.99402289e-01, -5.21160106e-07 ,-6.60931206e-02 }, { -2.18481332e-01, -3.65660965e-02 ,-2.76270937e-01 , 6.37817927e-01, -2.25210248e-01 ,-2.57545543e-11 , 5.04407490e-01 , 3.25644418e-01, -1.67397865e-06 ,-3.38918731e-01 }, { 4.30656416e-01 ,-6.05850820e-01 , 3.56411868e-01 , 1.39871104e-01, 1.61133433e-02, 1.95278541e-11, 4.25782008e-01 ,9.79111337e-01, -9.56787789e-07, -3.11803801e-01 }, { -2.36239573e-01 ,-1.73015706e-01 , 3.71253420e-01 ,-4.43126520e-01, -6.16987099e-01, -3.47112370e-11 ,-9.48308722e-02 , 2.35392910e-01, 3.90978755e-07 ,-5.30585275e-01 }, { -9.21914745e-03 , 2.10569685e-01 , 5.86744516e-01, -3.29272382e-01, 6.87882591e-02 ,-5.60479430e-11, -1.31813225e-01 ,-9.01748595e-02, 1.48535772e-06 ,7.75831897e-02 }, { -3.87850229e-02 , 2.12077616e-02 , 3.81875744e-02 ,1.12848455e-01, 1.83825444e-01, -1.18965572e-10 ,1.27163810e-01, 9.96867991e-02, 1.84582238e-06 ,7.19917185e-02 }, { -5.18885615e-02 ,-1.74264405e-01 ,2.27000308e-01, -4.29314728e-01, -1.17003563e-01, -2.81658523e-11 , 1.17201003e-01 ,-3.07566778e-01, -2.01403760e-06 ,-9.42299766e-02 }, { 4.90024471e-01 , 3.71047916e-02 , 1.01772677e-01, 9.51157739e-02, -1.71601670e-01 ,9.38432195e-11 , 6.24270660e-01, -4.71965703e-01, -3.31362503e-07 , 4.29190240e-01 }, { 7.14228024e-02 ,-5.00837424e-02 , 1.47659839e-01 , 5.17815234e-02, 3.52253877e-01 ,4.90728233e-11 , 2.23559528e-01 ,-2.22637845e-01, -1.25922349e-06 , 2.04710832e-01 }, { -1.36544728e-01 ,-1.49882902e-03 , 1.16554738e-01 ,-1.07862765e-01, 9.45728675e-02 , 2.68435951e-11 ,-2.67820297e-02, 1.89775976e-01, -2.41099251e-06, -1.34862793e-01 } }; float w1[10][10] = { { -0.23780609 ,-0.20482226 , 0.41957468, 0.40999775, 0.38139455 ,0.49962715, 0.08417365 , 0.29976534 ,-0.08972183 ,-0.0574983 }, { 0.07750195 ,-0.75130445 ,-0.06468749 ,-0.09033038 ,-0.18993429 ,0.82029747, -0.61669163 , 0.01430632 , 0.07597411, 0.27505365 }, { 0.49405426, 0.01242133 ,0.25904818 ,0.41172925 ,0.07578099 ,0.06032476, 0.46222851, 0.06112816, 0.23961187, 0.11556222 }, { 1.03532351 , 0.00237677 ,-1.41761159 , 0.2577502 ,-0.29667514 ,-0.22258016, 1.01807614, 0.47470323 , 0.64205134 , 1.17553243 }, { -0.54341226 , 0.05698822 ,-0.63832775 ,-0.3224985, -0.08834335 ,-0.20154572, 0.33619324 , 0.53621269 ,-0.08154711 , 0.10801987 }, { -1.43359900e-10, -2.19706358e-11 ,-7.62980145e-11 , 3.80564307e-11, 1.43483774e-10 ,1.43472783e-10 ,-7.14971534e-11 ,-4.57497718e-11, -7.01573521e-11 , 1.53484506e-10 }, { -0.27199681, -0.06586821 , 0.06227236 ,0.50916823 ,0.12266234 , 0.25784538, 0.21391334 ,-0.04650493 ,-0.21507827 ,-0.81284655 }, { 0.07606676, 0.13142832 ,-0.53617744 , 0.42486831 , 0.89048667 , 0.3048935, -0.71382582, -0.61000717 ,0.2688673 , 0.47569795 }, { 1.52424197e-07 , 6.22315298e-08 - 6.52738940e-11 ,-8.68034280e-07, -5.31746214e-07 ,-1.78368165e-07 ,-2.11015294e-08, -1.52950988e-06, -3.42529575e-11, 2.35200781e-07 }, { -0.9658597 ,-0.68771416, -0.14909613, -0.27739111 , 0.38529542, 0.14808103, -0.24781566 ,-0.52709518 ,0.07968214 ,-1.09388288 } }; float w2[10][4] = { { -5.53134378e-01, -5.05213046e-02, 1.17674467e+00, 1.71470806e-10 }, { 4.66713499e-01, 4.28506910e-01, -9.50886462e-02, 1.16200494e-10 }, { 2.57455827e-01, -3.01318414e-02, -4.42330819e-01, 1.27572777e-10 }, { 4.97257812e-02 ,1.68243289e-01 ,4.46669062e-01 ,2.76339875e-11 }, { -2.00255754e-01, 3.68610428e-01 , 2.01173992e-01, -6.76783395e-11 }, { -6.26138176e-02, -5.74267944e-01, 3.32356077e-01 ,-6.16432376e-12 }, { 5.33413965e-02, -5.74108504e-02 ,-7.05800150e-01 ,-1.82851013e-10 }, { -1.06458783e+00 ,-1.52935556e-01 ,-1.45886105e+00 ,-1.01166814e-10 }, { 2.78628319e-08, 2.87125783e-01 ,-1.52646659e+00 ,-1.70692624e-10 }, { -2.66851493e-01 ,-4.95637535e-02 , 7.59249111e-01 ,-6.39687400e-11 } }; float w3[4][2] = { { 0.34269875 ,0.28160403 },{ -0.2269393 , 0.46291535 },{ 0.35116205 ,0.32428314 },{ 4.44950996e-11 ,-1.64150986e-10 } }; float b0[10] = { -0.16749457 , 0.51837033 , 0.38030122 , 0.2287536 , 0.31281455 ,-0.31270079, -0.23713096, -0.27459556 ,-0.0780897 , 0.78092204 }; float b1[10] = { -0.19847084 , 0.51427174 ,0.16520637 , 0.02815113 ,0.14546747 ,-0.33054209, -0.22630977 ,-0.21777402 ,-0.68041806 ,-0.51254995 }; float b2[4] = { 0.10842243 , 0.55213982 ,-0.18210444, -0.43683546 }; float b3[2] = { 0.22007598, -0.15169636 }; if (nentry < 3 || nentry >(m_nWidth - 3)) return; for (int i = nstart; i < nend; i++) { if (i < 2 || i >(m_nHeight - 3)) { image[i * m_nWidth + nentry - 1] = image[i * m_nWidth + nentry - 2]; image[i * m_nWidth + nentry] = image[i * m_nWidth + nentry + 1]; } else { float x0[1][20]; int count = 0; float maxP = 0; float minP = 1e9; for (int k = -3; k <= 2; k++) { if (k == -1 || k == 0) continue; for (int l = -2; l <= 2; l++) { *((float*)x0 + count) = float(image[(i + l)* m_nWidth + (nentry + k)]); count++; maxP = max(maxP, float(image[(i + l)* m_nWidth + (nentry + k)])); minP = min(minP, float(image[(i + l)* m_nWidth + (nentry + k)])); } } if ((maxP - minP) > 2560) { maxP = min(maxP + 256, 65535.0f); minP = max(minP - 256, 0.0f); } if((maxP - minP) < 1)maxP = minP + 1; for (int k = 0; k < 20; k++) { *((float*)x0 + k) = (*((float*)x0 + k) - minP) / (maxP - minP); } float z1[1][20]; float x1[1][20]; float z2[1][10]; float x2[1][10]; float z3[1][5]; float x3[1][5]; float z4[1][2]; float y[1][2]; matMul((float**)w0, 20, 10, (float**)x0, 1, 20, b0, (float**)z1); relu((float**)z1, 1, 10, (float**)x1); matMul((float**)w1, 10, 10, (float**)x1, 1, 10, b1, (float**)z2); relu((float**)z2, 1, 10, (float**)x2); matMul((float**)w2, 10, 4, (float**)x2, 1, 10, b2, (float**)z3); relu((float**)z3, 1, 4, (float**)x3); matMul((float**)w3, 4, 2, (float**)x3, 1, 4, b3, (float**)z4); relu((float**)z4, 1, 2, (float**)y); float predict1 = max(min(*((float*)y) * (maxP - minP) + minP, 65535.0f), 0.0f); float predict2 = max(min(*((float*)y + 1) * (maxP - minP) + minP, 65535.0f), 0.0f); float flag1line1 = float(image[i * m_nWidth + (nentry - 3)])/ 2 + float(image[i * m_nWidth + (nentry + 1)]) / 2; float flag1line2 = float(image[i * m_nWidth + (nentry - 2)]) / 2 + float(image[i * m_nWidth + (nentry + 2)]) / 2; float flag1score = abs(flag1line1 - predict1) + abs(flag1line2 - predict2); if (flag1score < 30) { image[i * m_nWidth + (nentry - 1)] = WORD(max(min(flag1line1, 65535.0f), 0.0f)); image[i * m_nWidth + nentry] = WORD(max(min(flag1line2, 65535.0f), 0.0f)); } else { image[i * m_nWidth + (nentry - 1)] = WORD(predict1); image[i * m_nWidth + nentry] = WORD(predict2); } } } } bool CPixMatrix::LoadDLineMap( const char *fileName ) { FILE *fp; int *line_direction = new int; int *line_entries = new int; int *startpoint = new int; int *endpoint = new int; char *data_in = NULL; data_in = new char [MAX_PIX_MAP_LINE]; LINE_MAP2 * m_DLineMapCur = NULL; if(data_in == NULL) { return FALSE; } fp = fopen(fileName, "rb"); if(fp == NULL) { return FALSE; } FreeDBadLineMap(); m_doubleLineMap = NULL; while(fgets(data_in, MAX_PIX_MAP_LINE, fp) != NULL) { if(sscanf(data_in, "%d,%d:%d,%d", line_direction, line_entries, startpoint, endpoint) == 4) { // line_direction = 0;line_entries=359, startpoint=45, endpoint=2700; m_DLineMapCur = new LINE_MAP2; m_DLineMapCur->nLineType = *line_direction; m_DLineMapCur->startpoint = max(2, *startpoint); if(m_DLineMapCur->nLineType == 0) { m_DLineMapCur->line_entries = min(m_nHeight-1, max(1,*line_entries)); m_DLineMapCur->endpoint = min(m_nWidth-2, *endpoint); } else { m_DLineMapCur->line_entries = min(m_nWidth-1, max(1,*line_entries)); m_DLineMapCur->endpoint = min(m_nHeight-2, *endpoint); } m_DLineMapCur->nextline = m_doubleLineMap; m_doubleLineMap = m_DLineMapCur; } } if(fp != NULL) { fclose(fp); } if(data_in != NULL) { delete [] data_in; } delete line_direction; delete line_entries; delete startpoint; delete endpoint; return TRUE; } bool CPixMatrix::MarkAdjacentLine( LINE_MAP *m_linemap) { LINE_MAP *temp_linemap; WORD lineentry, llineentry, rlineentry; while(m_linemap) { lineentry = m_linemap->line_entries; llineentry = lineentry-1; rlineentry = lineentry+1; temp_linemap = m_linemap->nextline; //check through the line to find out adjacent line while(temp_linemap) { lineentry = temp_linemap->line_entries; if(lineentry == llineentry) { m_linemap->lLine = TRUE; temp_linemap->rLine = TRUE; } if(lineentry == rlineentry) { m_linemap->rLine = TRUE; temp_linemap->lLine = TRUE; } temp_linemap = temp_linemap->nextline; } //next one m_linemap = m_linemap->nextline; } return TRUE; } void CPixMatrix::CorrectLines(WORD* image) { int i,i1,i2,j,j1,j2; DWORD avepoint, avesurrond; WORD temp; LINE_MAP *m_LineMapCur; LINE_MAP *temp_linemap; LINE_MAP *left_linemap = NULL; //first cycle m_LineMapCur = m_xLineMap; while(m_LineMapCur) { if((m_LineMapCur->lLine==FALSE)&&(m_LineMapCur->rLine==FALSE)) { //line correction i = m_LineMapCur->line_entries; i1 = i-1; i2 = i+1; temp = image[i*m_nWidth+(m_LineMapCur->startpoint)-1]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[i*m_nWidth+j]+temp+image[i*m_nWidth+j2])/4; avesurrond = (2*image[i1*m_nWidth+j]+image[i1*m_nWidth+j1]+image[i1*m_nWidth+j2]+2*image[i2*m_nWidth+j]+image[i2*m_nWidth+j1]+image[i2*m_nWidth+j2])/8; temp = image[i*m_nWidth+j]; image[i*m_nWidth+j] = WORD(image[i*m_nWidth+j]*avesurrond/avepoint); } } else if((m_LineMapCur->lLine==TRUE)&&(m_LineMapCur->rLine==FALSE)) { //line correction i = m_LineMapCur->line_entries; // i1 = i-1; i2 = i+1; temp = image[i*m_nWidth+(m_LineMapCur->startpoint)-1]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[i*m_nWidth+j]+temp+image[i*m_nWidth+j2])/4; avesurrond = (2*image[i2*m_nWidth+j]+image[i2*m_nWidth+j1]+image[i2*m_nWidth+j2])/4; temp = image[i*m_nWidth+j]; image[i*m_nWidth+j] = WORD(image[i*m_nWidth+j]*avesurrond/avepoint); } } else if((m_LineMapCur->lLine==FALSE)&&(m_LineMapCur->rLine==TRUE)) { //line correction i = m_LineMapCur->line_entries; i1 = i-1; // i2 = i+1; temp = image[i*m_nWidth+(m_LineMapCur->startpoint)-1]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[i*m_nWidth+j]+temp+image[i*m_nWidth+j2])/4; avesurrond = (2*image[i1*m_nWidth+j]+image[i1*m_nWidth+j1]+image[i1*m_nWidth+j2])/4; temp = image[i*m_nWidth+j]; image[i*m_nWidth+j] = WORD(image[i*m_nWidth+j]*avesurrond/avepoint); } } else { //skip, next cycle to correction temp_linemap = new LINE_MAP; temp_linemap->nextline = left_linemap; temp_linemap->line_entries = m_LineMapCur->line_entries; temp_linemap->lLine = FALSE; temp_linemap->rLine = FALSE; temp_linemap->startpoint = m_LineMapCur->startpoint; temp_linemap->endpoint = m_LineMapCur->endpoint; left_linemap = temp_linemap; } m_LineMapCur = m_LineMapCur->nextline; } while(left_linemap) { m_LineMapCur = left_linemap; left_linemap = NULL; MarkAdjacentLine(m_LineMapCur); while(m_LineMapCur) { if((m_LineMapCur->lLine==FALSE)&&(m_LineMapCur->rLine==FALSE)) { i = m_LineMapCur->line_entries; i1 = i-1; i2 = i+1; temp = image[i*m_nWidth+(m_LineMapCur->startpoint)-1]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[i*m_nWidth+j]+temp+image[i*m_nWidth+j2])/4; avesurrond = (2*image[i1*m_nWidth+j]+image[i1*m_nWidth+j1]+image[i1*m_nWidth+j2]+2*image[i2*m_nWidth+j]+image[i2*m_nWidth+j1]+image[i2*m_nWidth+j2])/8; temp = image[i*m_nWidth+j]; image[i*m_nWidth+j] = WORD(image[i*m_nWidth+j]*avesurrond/avepoint); } } else if((m_LineMapCur->lLine==TRUE)&&(m_LineMapCur->rLine==FALSE)) { i = m_LineMapCur->line_entries; // i1 = i-1; i2 = i+1; temp = image[i*m_nWidth+(m_LineMapCur->startpoint)-1]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[i*m_nWidth+j]+temp+image[i*m_nWidth+j2])/4; avesurrond = (2*image[i2*m_nWidth+j]+image[i2*m_nWidth+j1]+image[i2*m_nWidth+j2])/4; temp = image[i*m_nWidth+j]; image[i*m_nWidth+j] = WORD(image[i*m_nWidth+j]*avesurrond/avepoint); } } else if((m_LineMapCur->lLine==FALSE)&&(m_LineMapCur->rLine==TRUE)) { i = m_LineMapCur->line_entries; i1 = i-1; // i2 = i+1; temp = image[i*m_nWidth+(m_LineMapCur->startpoint)-1]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[i*m_nWidth+j]+temp+image[i*m_nWidth+j2])/4; avesurrond = (2*image[i1*m_nWidth+j]+image[i1*m_nWidth+j1]+image[i1*m_nWidth+j2])/4; temp = image[i*m_nWidth+j]; image[i*m_nWidth+j] = WORD(image[i*m_nWidth+j]*avesurrond/avepoint); } } else { temp_linemap = new LINE_MAP; temp_linemap->nextline = left_linemap; temp_linemap->line_entries = m_LineMapCur->line_entries; temp_linemap->lLine = FALSE; temp_linemap->rLine = FALSE; temp_linemap->startpoint = m_LineMapCur->startpoint; temp_linemap->endpoint = m_LineMapCur->endpoint; left_linemap = temp_linemap; } temp_linemap = m_LineMapCur; m_LineMapCur = m_LineMapCur->nextline; delete temp_linemap; } } //first cycle m_LineMapCur = m_yLineMap; while(m_LineMapCur) { if((m_LineMapCur->lLine==FALSE)&&(m_LineMapCur->rLine==FALSE)) { //line correction i = m_LineMapCur->line_entries; i1 = i-1; i2 = i+1; temp = image[((m_LineMapCur->startpoint)-1)*m_nWidth+i]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[j*m_nWidth+i]+temp+image[j2*m_nWidth+i])/4; avesurrond = (2*image[j*m_nWidth+i1]+image[j1*m_nWidth+i1]+image[j2*m_nWidth+i1]+2*image[j*m_nWidth+i2]+image[j1*m_nWidth+i2]+image[j2*m_nWidth+i2])/8; temp = image[j*m_nWidth+i]; image[j*m_nWidth+i] = WORD(image[j*m_nWidth+i]*avesurrond/avepoint); } } else if((m_LineMapCur->lLine==TRUE)&&(m_LineMapCur->rLine==FALSE)) { //line correction i = m_LineMapCur->line_entries; // i1 = i-1; i2 = i+1; temp = image[((m_LineMapCur->startpoint)-1)*m_nWidth+i]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[j*m_nWidth+i]+temp+image[j2*m_nWidth+i])/4; avesurrond = (2*image[j*m_nWidth+i2]+image[j1*m_nWidth+i2]+image[j2*m_nWidth+i2])/4; temp = image[j*m_nWidth+i]; image[j*m_nWidth+i] = WORD(image[j*m_nWidth+i]*avesurrond/avepoint); } } else if((m_LineMapCur->lLine==FALSE)&&(m_LineMapCur->rLine==TRUE)) { //line correction i = m_LineMapCur->line_entries; i1 = i-1; // i2 = i+1; temp = image[((m_LineMapCur->startpoint)-1)*m_nWidth+i]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[j*m_nWidth+i]+temp+image[j2*m_nWidth+i])/4; avesurrond = (2*image[j*m_nWidth+i1]+image[j1*m_nWidth+i1]+image[j2*m_nWidth+i1])/4; temp = image[j*m_nWidth+i]; image[j*m_nWidth+i] = WORD(image[j*m_nWidth+i]*avesurrond/avepoint); } } else { //skip, next cycle to correction temp_linemap = new LINE_MAP; temp_linemap->nextline = left_linemap; temp_linemap->line_entries = m_LineMapCur->line_entries; temp_linemap->lLine = FALSE; temp_linemap->rLine = FALSE; temp_linemap->startpoint = m_LineMapCur->startpoint; temp_linemap->endpoint = m_LineMapCur->endpoint; left_linemap = temp_linemap; } m_LineMapCur = m_LineMapCur->nextline; } while(left_linemap) { m_LineMapCur = left_linemap; left_linemap = NULL; MarkAdjacentLine(m_LineMapCur); while(m_LineMapCur) { if((m_LineMapCur->lLine==FALSE)&&(m_LineMapCur->rLine==FALSE)) { i = m_LineMapCur->line_entries; i1 = i-1; i2 = i+1; temp = image[((m_LineMapCur->startpoint)-1)*m_nWidth+i]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[j*m_nWidth+i]+temp+image[j2*m_nWidth+i])/4; avesurrond = (2*image[j*m_nWidth+i1]+image[j1*m_nWidth+i1]+image[j2*m_nWidth+i1]+2*image[j*m_nWidth+i2]+image[j1*m_nWidth+i2]+image[j2*m_nWidth+i2])/8; temp = image[j*m_nWidth+i]; image[j*m_nWidth+i] = WORD(image[j*m_nWidth+i]*avesurrond/avepoint); } } else if((m_LineMapCur->lLine==TRUE)&&(m_LineMapCur->rLine==FALSE)) { i = m_LineMapCur->line_entries; // i1 = i-1; i2 = i+1; temp = image[((m_LineMapCur->startpoint)-1)*m_nWidth+i]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[j*m_nWidth+i]+temp+image[j2*m_nWidth+i])/4; avesurrond = (2*image[j*m_nWidth+i2]+image[j1*m_nWidth+i2]+image[j2*m_nWidth+i2])/4; temp = image[j*m_nWidth+i]; image[j*m_nWidth+i] = WORD(image[j*m_nWidth+i]*avesurrond/avepoint); } } else if((m_LineMapCur->lLine==FALSE)&&(m_LineMapCur->rLine==TRUE)) { i = m_LineMapCur->line_entries; i1 = i-1; // i2 = i+1; temp = image[((m_LineMapCur->startpoint)-1)*m_nWidth+i]; for( j = (m_LineMapCur->startpoint); j<(m_LineMapCur->endpoint); j++) { j1 = j-1; j2 = j+1; avepoint = (2*image[j*m_nWidth+i]+temp+image[j2*m_nWidth+i])/4; avesurrond = (2*image[j*m_nWidth+i1]+image[j1*m_nWidth+i1]+image[j2*m_nWidth+i1])/4; temp = image[j*m_nWidth+i]; image[j*m_nWidth+i] = WORD(image[j*m_nWidth+i]*avesurrond/avepoint); } } else { temp_linemap = new LINE_MAP; temp_linemap->nextline = left_linemap; temp_linemap->line_entries = m_LineMapCur->line_entries; temp_linemap->lLine = FALSE; temp_linemap->rLine = FALSE; temp_linemap->startpoint = m_LineMapCur->startpoint; temp_linemap->endpoint = m_LineMapCur->endpoint; left_linemap = temp_linemap; } temp_linemap = m_LineMapCur; m_LineMapCur = m_LineMapCur->nextline; delete temp_linemap; } } } bool CPixMatrix::FreeLineMap(LINE_MAP *m_linemap) { LINE_MAP *temp_linemap; while(m_linemap) { temp_linemap = m_linemap; m_linemap = m_linemap->nextline; delete temp_linemap; } m_linemap = NULL; return TRUE; } //开始自动坏点校正 void CPixMatrix::BeginAutoBadPixels() { //if(m_lastImg) //{ // delete [] m_lastImg; // m_lastImg = NULL; //} if(m_mapImg) { delete [] m_mapImg; m_mapImg = NULL; } //m_lastImg = new WORD[m_nWidth*m_nHeight]; m_mapImg = new WORD[m_nWidth*m_nHeight]; ASSERT(m_mapImg); ZeroMemory(m_mapImg, m_nWidth*m_nHeight*sizeof(WORD)); m_curAvg = -1; m_lastAvg = -1; } void CPixMatrix::AddImageforBadPixels(WORD *wImage) { if (wImage == NULL) { return; } //m_curImg = wImage;////////////////////////chenGN 2013.01.31 int ntempHOffset = max(0, m_nHOffset); int ntempWOffset = max(0, m_nWOffset); bool bFlag = DetBadPxlByMF(wImage, m_nWidth, m_nHeight, ntempWOffset, ntempHOffset, m_mapImg);////////////////////////chenGN 2013.01.31 if (!bFlag) { delete []m_mapImg; return; } //old code delete 20100906 //calculate avg pv /*DWORD dwSum = 0; DWORD dwIndex = 0; int i, j; DWORD dwCts = 0; for(i = ntempHOffset; i < m_nHeight-ntempHOffset; i += 8) { dwIndex = i*m_nWidth; for(j = ntempWOffset; j < m_nWidth-ntempWOffset; j+= 8) { dwSum += (*(m_curImg + dwIndex + j)); dwCts++; } } m_curAvg = dwSum/dwCts; //find badpixel by thresdhold; int thresdhold1, thresdhold2; thresdhold1 = m_curAvg*0.6; thresdhold2 = (m_curAvg*1.4>65535?65535:m_curAvg*1.4); for(i = ntempHOffset; i < m_nHeight-ntempHOffset; i ++) { dwIndex = i*m_nWidth; for(j = ntempWOffset; j < m_nWidth-ntempWOffset; j++) { if(( *(m_curImg + dwIndex + j) < thresdhold1)||( *(m_curImg + dwIndex + j) > thresdhold2)) { *(m_mapImg + dwIndex + j) = 0xFFFF; } } } AutoBadPointDec(m_curImg,m_nWidth, m_nHeight ,ntempHOffset, ntempWOffset,m_mapImg); //check status; if(m_lastAvg<0) { memcpy(m_lastImg, m_curImg, m_nHeight*m_nWidth*sizeof(WORD)); m_lastAvg = m_curAvg; m_curAvg = -1; //no last Image; return; } else if(abs(m_curAvg - m_lastAvg)<500) { //not too many difference; return; } else { double thresdhold1 = (((double) m_curAvg) / m_lastAvg)*0.9; double thresdhold2 = (((double) m_curAvg) / m_lastAvg)*1.1; double temp=0.0; for(i = ntempHOffset; i < m_nHeight-ntempHOffset; i ++) { dwIndex = i*m_nWidth; for(j = ntempWOffset; j < m_nWidth-ntempWOffset; j++) { if (*(m_lastImg + dwIndex + j)==0) continue; temp=((double)*(m_curImg + dwIndex + j))/(*(m_lastImg + dwIndex + j)); if((temp < thresdhold1)||(temp>thresdhold2)) { *(m_mapImg + dwIndex + j) = 0xFFFF; } } } memcpy(m_lastImg, m_curImg, m_nHeight*m_nWidth*sizeof(WORD)); m_lastAvg = m_curAvg; m_curAvg = -1; } */ } //结束自动换点校正,-1,放弃;0,替换原有map;1,合并原有map void CPixMatrix::EndAutoBadPixels(int nMode) { bool bReturn = true; if(nMode == 0) { //0,替换原有map FreeBadPixelMap(); bReturn = AutoBadPixelMap2(m_mapImg); if (bReturn) { SaveBadPixelMap(m_charFilename); } } else if(nMode == 1) { //1,合并原有map bReturn = AutoBadPixelMap2(m_mapImg); if (bReturn) { SaveBadPixelMap(m_charFilename); } } else { //-1,放弃 } //if(m_lastImg)////////////////////////chenGN 2013.01.31 //{ // delete [] m_lastImg; // m_lastImg = NULL; //} if(m_mapImg) { delete [] m_mapImg; m_mapImg = NULL; } m_curAvg = -1; m_lastAvg = -1; } //add by wangyb 2013 for replace the previous function EndAutoBadPixels() //the purpose is to carry on the same process with Gain Calibration; //结束自动换点校正,-1,放弃;0,替换原有map;1,合并原有map void CPixMatrix::StoreBadPixels(const char * charFilename,int nMode) { bool bReturn = true; if(nMode == 0) { //0,替换原有map FreeBadPixelMap(); bReturn = AutoBadPixelMap2(m_mapImg); if (bReturn) { SaveBadPixelMap(charFilename); } } else if(nMode == 1) { //1,合并原有map bReturn = AutoBadPixelMap2(m_mapImg); if (bReturn) { SaveBadPixelMap(charFilename); } } else { //-1,放弃 } //if(m_lastImg)////////////////////////chenGN 2013.01.31 //{ // delete [] m_lastImg; // m_lastImg = NULL; //} if(m_mapImg) { delete [] m_mapImg; m_mapImg = NULL; } m_curAvg = -1; m_lastAvg = -1; } void CPixMatrix::CorrectButCross(WORD* image) { } bool CPixMatrix::AutoBadPointDec(unsigned short* lpDetail,int lWidth, int lHeight ,int Xoffset, int Yoffset,unsigned short* pmap) { unsigned short* lpNewDataBits =lpDetail; // new unsigned short[lWidth*lHeight]; // memcpy(lpNewDataBits,lpDetail,sizeof(unsigned short)*lWidth*lHeight); int sort1[4];//big int sort2[4];//small int sort3[3];//big int sort4[3];//small double Neighbor_sum=0; double Neighbor_avg=0; long i,j; //for loop int temp; int moveoff; int locallength=50; //区域直方图长度 int start_avg; start_avg=GetAvg(lpNewDataBits,lWidth,lHeight,Xoffset ,Yoffset,locallength); // int last_avg=start_avg; for(i = Xoffset; i=lHeight) // moveoff=lHeight-Xoffset-locallength; // else // moveoff=i; // start_avg=GetAvg(lpNewDataBits,lWidth,lHeight,moveoff,Yoffset,locallength); start_avg=last_avg; for(j = Yoffset; jlpNewDataBits[(i+1)*lWidth+j+1]) { sort1[0] = lpNewDataBits[(i-1)*lWidth+j-1]; sort2[0] = lpNewDataBits[(i+1)*lWidth+j+1]; } else { sort1[0] = lpNewDataBits[(i+1)*lWidth+j+1]; sort2[0] = lpNewDataBits[(i-1)*lWidth+j-1]; } if(lpNewDataBits[(i-1)*lWidth+j]>lpNewDataBits[(i+1)*lWidth+j]) { sort1[1] = lpNewDataBits[(i-1)*lWidth+j]; sort2[1] = lpNewDataBits[(i+1)*lWidth+j]; } else { sort1[1] = lpNewDataBits[(i+1)*lWidth+j]; sort2[1] = lpNewDataBits[(i-1)*lWidth+j]; } if(lpNewDataBits[(i-1)*lWidth+j+1]>lpNewDataBits[(i+1)*lWidth+j-1]) { sort1[2] = lpNewDataBits[(i-1)*lWidth+j+1]; sort2[2] = lpNewDataBits[(i+1)*lWidth+j-1]; } else { sort1[2] = lpNewDataBits[(i+1)*lWidth+j-1]; sort2[2] = lpNewDataBits[(i-1)*lWidth+j+1]; } if(lpNewDataBits[i*lWidth+j-1]>lpNewDataBits[i*lWidth+j+1]) { sort1[3] = lpNewDataBits[i*lWidth+j-1]; sort2[3] = lpNewDataBits[i*lWidth+j+1]; } else { sort1[3] = lpNewDataBits[i*lWidth+j+1]; sort2[3] = lpNewDataBits[i*lWidth+j-1]; } //delete the max of the sort1[4]; if (sort1[0]>sort1[2]) { temp=sort1[2]; sort1[2]=sort1[0]; sort1[0]=temp; } if (sort1[1]>sort1[3]) { temp=sort1[3]; sort1[3]=sort1[1]; sort1[1]=temp; } if (sort1[2]>sort1[3]) { sort1[2]=sort1[3]; } if (sort2[0]sort2[0]) { sort3[0]=sort1[0]; sort4[0]=sort2[0]; } else { sort3[0]=sort2[0]; sort4[0]=sort1[0]; } if (sort1[1]>sort2[1]) { sort3[1]=sort1[1]; sort4[1]=sort2[1]; } else { sort3[1]=sort2[1]; sort4[1]=sort1[1]; } if (sort1[2]>sort2[2]) { sort3[2]=sort1[2]; sort4[2]=sort2[2]; } else { sort3[2]=sort2[2]; sort4[2]=sort1[2]; } //将这六个值相加,后减去一个最大值和最小值. Neighbor_sum=sort3[0]+sort3[1]+sort3[2]+sort4[0]+sort4[1]+sort4[2]; //剩余三个点计算均值 if (sort3[0]>sort3[1]) { if (sort3[0]>sort3[2]) Neighbor_sum= Neighbor_sum-sort3[0]; else Neighbor_sum= Neighbor_sum-sort3[2]; } else { if (sort3[1]>sort3[2]) Neighbor_sum= Neighbor_sum-sort3[1]; else Neighbor_sum= Neighbor_sum-sort3[2]; } //找最小值 if (sort4[0]start_avg*0.8)) { start_avg=Neighbor_avg; } else { int tempccc = 0; } if((*(lpNewDataBits+i*lWidth+j)>start_avg*1.2)||(*(lpNewDataBits+i*lWidth+j)0.2)&&(rate<0.8)) { count+=hist[i]; sumsum+=hist[i]*i; } } avg=sumsum/count; delete []hist; return avg; } //code begin 20100906 /************************************************************************ FUNCTION NAME: Mean7 DESCRIPTION: Filter raw image by 7 * 7 mean filter RETURN VALUE: PARA: [IN\OUT] pImgData: raw image data [IN] nWidth: raw image width [IN] nHeight: raw image height [IN] nXOffset: raw image's offset in x direction [IN] nYOffset: raw image's offset in y direction HISTORY: Aug\24\2010 written by Alex Stocks ************************************************************************/ /* int CPixMatrix::Mean7(ushort_t *pImgData, int nWidth, int nHeight, int nXOffset, int nYOffset) { if (NULL == pImgData || nWidth <= 2 * nXOffset + 7 || nXOffset < 0 || nHeight <= 2 * nYOffset + 7 || nYOffset < 0) { return -1; } HGLOBAL hImgBuffer = ::GlobalAlloc(GHND, nHeight * nWidth * sizeof(ushort_t)); if (NULL == hImgBuffer) { ::GlobalUnlock(hImgBuffer); return -1; } ushort_t* pImgBuffer = (ushort_t*) ::GlobalLock(hImgBuffer); int nMinXIdx = nXOffset; int nMaxXIdx = nWidth - nXOffset; int nMinYIdx = nYOffset; int nMaxYIdx = nHeight - nYOffset; int nIdxI = 0; int nIdxJ = 0; int nIndex = 0; ushort_t* pBuffer = NULL; ushort_t* pData = NULL; for (nIdxI = nMinYIdx; nIdxI < nMaxYIdx; ++nIdxI) { nIndex = nIdxI * nWidth + nMinXIdx; pBuffer = pImgBuffer + nIndex; pData = pImgData + nIndex; *(pBuffer) = (*(pData) + 2 * (*(pData + 1)) + 2 * (*(pData + 2)) + 2 * (*(pData + 3))) / 7; *(pBuffer + 1) = (*(pData) + 2 * (*(pData + 1)) + 2 * (*(pData + 2)) + *(pData + 3) + *(pData + 4)) / 7; *(pBuffer + 2) = (*(pData) + 2 *(*(pData + 1)) + *(pData + 2) + *(pData + 3) + *(pData + 4) + *(pData + 5)) / 7; nIndex -= nMinXIdx; for (nIdxJ = nMinXIdx + 3; nIdxJ < nMaxXIdx - 3; ++nIdxJ) { *(pBuffer + nIdxJ) = (*(pData + nIdxJ - 3) + *(pData + nIdxJ - 2) + *(pData + nIdxJ - 1) + *(pData + nIdxJ) + *(pData + nIdxJ + 1) + *(pData + nIdxJ + 2) + *(pData + nIdxJ + 3)) / 7; } nIndex += nMaxXIdx; pBuffer = pImgBuffer + nIndex; pData = pImgData + nIndex; *(pBuffer - 3) = (*(pData - 6) + *(pData - 5) + *(pData - 4) + *(pData - 3) + 2 * (*(pData - 2)) + *(pData - 1)) / 7; *(pBuffer - 2) = (*(pData -5) + *(pData -4) + 2 * (*(pData -3)) + 2 * (*(pData -2)) + *(pData -1)) / 7; *(pBuffer - 1) = (2 * (*(pData - 4)) + 2 * (*(pData - 3)) + 2 * (*(pData - 2)) + *(pData - 1) ) / 7; } int nInc1 = nWidth * 1; int nInc2 = nWidth * 2; int nInc3 = nWidth * 3; int nInc4 = nWidth * 4; int nInc5 = nWidth * 5; int nInc6 = nWidth * 6; int nGVSum = 0; int nStartYPos = 0; int nEndYPos = 0; for (nIdxI = nMinXIdx; nIdxI < nMaxXIdx; ++nIdxI) { nIndex = nMinYIdx * nWidth + nIdxI; pBuffer = pImgBuffer + nIndex; pData = pImgData + nIndex; *(pBuffer) = (*(pData) + 2 * (*(pData + nInc1)) + 2 * (*(pData + nInc2)) + 2 * (*(pData + nInc3))) / 7; *(pBuffer + nInc1) = (*(pData) + 2 * (*(pData + nInc1)) + 2 * (*(pData + nInc2)) + *(pData + nInc3) + *(pData + nInc4)) / 7; *(pBuffer + nInc2) = (*(pData) + 2 *(*(pData + nInc1)) + *(pData + nInc2) + *(pData + nInc3) + *(pData + nInc4) + *(pData + nInc5)) / 7; nIndex -= nMinYIdx * nWidth; nGVSum = *(pData) + *(pData + nInc1) + *(pData + nInc2) + *(pData + nInc3) + *(pData + nInc4) + *(pData + nInc5); nStartYPos = (nMinYIdx + 3) * nWidth + nIdxI; nEndYPos = (nMaxYIdx - 3) * nWidth + nIdxI; pBuffer = pImgBuffer; pData = pImgData; for (nIdxJ = nStartYPos; nIdxJ < nEndYPos; nIdxJ += nWidth) { nGVSum += *(pData + nIdxJ + nInc3); *(pBuffer + nIdxJ) = nGVSum / 7; nGVSum -= *(pBuffer + nIdxJ - nInc3); } nIndex = nMaxYIdx * nWidth + nIdxI; pBuffer = pImgBuffer + nIndex; pData = pImgData + nIndex; *(pBuffer - nInc3) = (*(pData - nInc6) + *(pData - nInc5) + *(pData - nInc4) + *(pData - nInc3) + 2 * (*(pData - nInc2)) + *(pData - nInc1)) / 7; *(pBuffer - nInc2) = (*(pData - nInc5) + *(pData - nInc4) + 2 * (*(pData - nInc3)) + 2 * (*(pData - nInc2)) + *(pData - nInc1)) / 7; *(pBuffer - nInc1) = (2 * (*(pData - nInc4)) + 2 * (*(pData - nInc3)) + 2 * (*(pData - nInc2)) + *(pData - nInc1) ) / 7; } memcpy(pImgData, pImgBuffer, nHeight * nWidth * sizeof(ushort_t)); ::GlobalUnlock(hImgBuffer); ::GlobalFree(hImgBuffer); return 1; } */ int CPixMatrix::Mean7(ushort_t *pImgData, int nWidth, int nHeight, int nXOffset, int nYOffset) { if (NULL == pImgData || nWidth <= 2 * nXOffset + 7 || nXOffset < 0 || nHeight <= 2 * nYOffset + 7 || nYOffset < 0) { return -1; } HGLOBAL hImgBuffer = ::GlobalAlloc(GHND, nHeight * nWidth * sizeof(ushort_t)); if (NULL == hImgBuffer) { ::GlobalUnlock(hImgBuffer); return -1; } ushort_t* pImgBuffer = (ushort_t*) ::GlobalLock(hImgBuffer); int nMinXIdx = nXOffset; int nMaxXIdx = nWidth - nXOffset; int nMinYIdx = nYOffset; int nMaxYIdx = nHeight - nYOffset; int nIdxI = 0; int nIdxJ = 0; int nIndex = 0; ushort_t* pBuffer = NULL; ushort_t* pData = NULL; for (nIdxI = nMinYIdx; nIdxI < nMaxYIdx; ++nIdxI) { nIndex = nIdxI * nWidth + nMinXIdx; pBuffer = pImgBuffer + nIndex; pData = pImgData + nIndex; *(pBuffer) = (*(pData) + 2 * (*(pData + 1)) + 2 * (*(pData + 2)) + 2 * (*(pData + 3))) / 7; *(pBuffer + 1) = (*(pData) + 2 * (*(pData + 1)) + 2 * (*(pData + 2)) + *(pData + 3) + *(pData + 4)) / 7; *(pBuffer + 2) = (*(pData) + 2 *(*(pData + 1)) + *(pData + 2) + *(pData + 3) + *(pData + 4) + *(pData + 5)) / 7; nIndex -= nMinXIdx; pBuffer = pImgBuffer + nIndex; pData = pImgData + nIndex; for (nIdxJ = nMinXIdx + 3; nIdxJ < nMaxXIdx - 3; ++nIdxJ) { *(pBuffer + nIdxJ) = (*(pData + nIdxJ - 3) + *(pData + nIdxJ - 2) + *(pData + nIdxJ - 1) + *(pData + nIdxJ) + *(pData + nIdxJ + 1) + *(pData + nIdxJ + 2) + *(pData + nIdxJ + 3)) / 7; } nIndex += nMaxXIdx; pBuffer = pImgBuffer + nIndex; pData = pImgData + nIndex; *(pBuffer - 3) = (*(pData - 6) + *(pData - 5) + *(pData - 4) + *(pData - 3) + 2 * (*(pData - 2)) + *(pData - 1)) / 7; *(pBuffer - 2) = (*(pData -5) + *(pData -4) + 2 * (*(pData -3)) + 2 * (*(pData -2)) + *(pData -1)) / 7; *(pBuffer - 1) = (2 * (*(pData - 4)) + 2 * (*(pData - 3)) + 2 * (*(pData - 2)) + *(pData - 1) ) / 7; } memcpy(pImgData, pImgBuffer, nHeight * nWidth * sizeof(ushort_t)); int nInc1 = nWidth * 1; int nInc2 = nWidth * 2; int nInc3 = nWidth * 3; int nInc4 = nWidth * 4; int nInc5 = nWidth * 5; int nInc6 = nWidth * 6; int nGVSum = 0; int nStartYPos = 0; int nEndYPos = 0; for (nIdxI = nMinXIdx; nIdxI < nMaxXIdx; ++nIdxI) { nIndex = nMinYIdx * nWidth + nIdxI; pBuffer = pImgBuffer + nIndex; pData = pImgData + nIndex; *(pBuffer) = (*(pData) + 2 * (*(pData + nInc1)) + 2 * (*(pData + nInc2)) + 2 * (*(pData + nInc3))) / 7; *(pBuffer + nInc1) = (*(pData) + 2 * (*(pData + nInc1)) + 2 * (*(pData + nInc2)) + *(pData + nInc3) + *(pData + nInc4)) / 7; *(pBuffer + nInc2) = (*(pData) + 2 *(*(pData + nInc1)) + *(pData + nInc2) + *(pData + nInc3) + *(pData + nInc4) + *(pData + nInc5)) / 7; nIndex -= nMinYIdx * nWidth; nGVSum = *(pData) + *(pData + nInc1) + *(pData + nInc2) + *(pData + nInc3) + *(pData + nInc4) + *(pData + nInc5); nStartYPos = (nMinYIdx + 3) * nWidth + nIdxI; nEndYPos = (nMaxYIdx - 3) * nWidth + nIdxI; pBuffer = pImgBuffer; pData = pImgData; for (nIdxJ = nStartYPos; nIdxJ < nEndYPos; nIdxJ += nWidth) { nGVSum += *(pData + nIdxJ + nInc3); *(pBuffer + nIdxJ) = nGVSum / 7; nGVSum -= *(pBuffer + nIdxJ - nInc3); } nIndex = nMaxYIdx * nWidth + nIdxI; pBuffer = pImgBuffer + nIndex; pData = pImgData + nIndex; *(pBuffer - nInc3) = (*(pData - nInc6) + *(pData - nInc5) + *(pData - nInc4) + *(pData - nInc3) + 2 * (*(pData - nInc2)) + *(pData - nInc1)) / 7; *(pBuffer - nInc2) = (*(pData - nInc5) + *(pData - nInc4) + 2 * (*(pData - nInc3)) + 2 * (*(pData - nInc2)) + *(pData - nInc1)) / 7; *(pBuffer - nInc1) = (2 * (*(pData - nInc4)) + 2 * (*(pData - nInc3)) + 2 * (*(pData - nInc2)) + *(pData - nInc1) ) / 7; } memcpy(pImgData, pImgBuffer, nHeight * nWidth * sizeof(ushort_t)); // CFile file; // CString strDignosisPath = _T("e:\\Varian.raw"); // file.Open(strDignosisPath, CFile::modeCreate | CFile::modeWrite ); // file.Write(pImgBuffer, m_nWidth*m_nHeight*sizeof(WORD)); // file.Close(); ::GlobalUnlock(hImgBuffer); ::GlobalFree(hImgBuffer); return 1; } /************************************************************************ FUNCTION NAME: CalcGlbAvgPxlValueBySamp DESCREPTION: Calculate global average pixel value by sampling method RETURN VALUE: Global average pixel value. PARA: [IN]pImgData: raw image data array [IN]nWidth: raw image's width [IN]nHeight: raw image's height [IN]nXOffset: raw image's offset in x direction [IN]nYOffset: raw image's offset in y direction HISTORY: August/2/2010 written by Alex Stocks ************************************************************************/ double CPixMatrix::CalcGlbAvgPxlValueBySamp(unsigned short* pImgData, int nWidth, int nHeight, int nXOffset, int nYOffset) { if (NULL == pImgData || nWidth < 0 || nHeight < 0 || nXOffset < 0 || nYOffset < 0 || nWidth <= 2 * nXOffset || nHeight <= 2 * nYOffset) { return -1.0f; } int nIdxI = 0; int nIdxJ = 0; int nIndex = 0; int nHist[PIXEL_MAX_VALUE] = { 0 }; int nMinYIdx = nYOffset; int nMaxYIdx = nHeight - nYOffset; int nMinXIdx = nXOffset; int nMaxXIdx = nWidth - nXOffset; unsigned short *pImage = pImgData; int nPxlNum = 0; for (nIdxI = nMinYIdx; nIdxI < nMaxYIdx; nIdxI += 8) { pImage = pImgData + nIdxI * nWidth; for (nIdxJ = nMinXIdx; nIdxJ < nMaxXIdx; nIdxJ += 8) { ++nHist[*(pImage+nIdxJ)]; ++nPxlNum; } } //code delete 20110125 // double fSum=0.0f; // double fGVSum = 0.0f; // double fGVAvg=0; // double fRatio = 0; // int nCount=0; // for (nIdxI = 0; nIdxI < 65535; ++nIdxI) // { // fSum += nHist[nIdxI]; // fRatio = fSum / nPxlNum; // if (0.15f < fRatio && fRatio < 0.85f) // { // nCount += nHist[nIdxI]; // fGVSum += nHist[nIdxI] * nIdxI; // } // } // if (nCount <= 0) // { // return -1.0f; // } //code begin 20110125 double fSum=0.0f; double fGVSum = 0.0f; double fGVAvg=0; double fRatio = 0; int nCount=0; float fTempGVSum = 0.0f; for (nIdxI = 0; nIdxI < 65535; ++nIdxI) { fSum += nHist[nIdxI]; fRatio = fSum / nPxlNum; fTempGVSum += nHist[nIdxI] * nIdxI; if (0.15f < fRatio && fRatio < 0.85f) { nCount += nHist[nIdxI]; fGVSum += nHist[nIdxI] * nIdxI; } } if (nCount <= 0) { nCount = nPxlNum; fGVSum = fTempGVSum; } //code end 20110125 fGVAvg = fGVSum / nCount; return fGVAvg; } ///////////////////////////////////redesigned DetBadPxlByMF by CGN 2013.01.30 bool CPixMatrix::DetBadPxlByMF(ushort_t *pImgData, int nWidth, int nHeight, int nXOffset, int nYOffset, ushort_t *pMap) { if (NULL == pImgData || NULL == pMap || nWidth <= 0 || nHeight <= 0 || nXOffset < 0 || nYOffset < 0 || nWidth <= 2 * nXOffset || nHeight <= 2 * nYOffset) { return false; } ///////////////////////////全图阈值计算,挑出黑白坏点 float fGlbAvgPxlValue = CalcGlbAvgPxlValueBySamp(pImgData, nWidth, nHeight, nXOffset, nYOffset); float fMinThreshold = 0.5f * fGlbAvgPxlValue; float fMaxThreshold = 1.5f * fGlbAvgPxlValue; if (65535.0f < fMaxThreshold) //可能是导致16位图像坏点过多判断的原因,16383修改为65535,by陈冠男,2012-12-20 { fMaxThreshold = 65535.0f; } int nMinXIdx = nXOffset; int nMaxXIdx = nWidth - nXOffset; int nMinYIdx = nYOffset; int nMaxYIdx = nHeight - nYOffset; int bcount = 0; for ( int i = nMinYIdx; i < nMaxYIdx; ++i ) { for ( int j = nMinXIdx; j < nMaxXIdx; ++j ) { if ( pImgData[ i * nWidth + j ] < fMinThreshold || fMaxThreshold < pImgData[ i * nWidth + j ] ) { pMap[ i * nWidth + j ] = 65535; bcount++; } } } /////////////////////////////////将图像分成4x4区域,在每个区域中用7x7像素模版进行坏点判断 /*int Heightbegin = nYOffset; int Heightend = nYOffset + ( nHeight - 2 * nYOffset ) / 4; int Widthbegin = nXOffset; int Widthend = nXOffset + ( nWidth - 2 * nXOffset ) / 4; int nsum = 0; int ncount = 0; int navg = 0; int nthres = 0; for ( int i = 0; i < 4; i++ ) { Widthbegin = nXOffset; Widthend = nXOffset + ( nWidth - 2 * nXOffset ) / 4; for ( int j = 0; j < 4; j++ ) { for ( int k = Heightbegin + 3; k < Heightend - 3 ; k++ ) { for ( int p = Widthbegin + 3; p < Widthend - 3; p++ ) { ncount = 0; nsum = 0; navg = 0; nthres = 0; if ( pMap[ k * nWidth + p ] != 65535 ) { for ( int m = -3; m < 4; m++ ) { for ( int n = -3; n < 4; n++ ) { if ( pMap[ ( k + m ) * nWidth + p + n ] != 65535 ) { nsum += pImgData[ ( k + m ) * nWidth + p + n ]; ncount++; } } } navg = nsum / ncount; nthres = navg / 10; if ( abs( pImgData[ k * nWidth + p ] - navg ) > nthres ) { pMap[ k * nWidth + p ] = 65535; bcount++; } } } } Widthbegin += ( nWidth - 2 * nXOffset ) / 4; Widthend += ( nWidth - 2 * nXOffset ) / 4; } Heightbegin += ( nHeight - 2 * nYOffset ) / 4; Heightend += ( nHeight - 2 * nYOffset ) / 4; }*/ int Heightbegin = nYOffset; int Heightend = nHeight - nYOffset; int Widthbegin = nXOffset; int Widthend = nWidth - nXOffset; int nsum = 0; int ncount = 0; int navg = 0; int nthres = 0; for ( int k = Heightbegin + 3; k < Heightend - 3 ; k++ ) { for ( int p = Widthbegin + 3; p < Widthend - 3; p++ ) { ncount = 0; nsum = 0; navg = 0; nthres = 0; if ( pMap[ k * nWidth + p ] != 65535 ) { for ( int m = -3; m < 4; m++ ) { for ( int n = -3; n < 4; n++ ) { if ( pMap[ ( k + m ) * nWidth + p + n ] != 65535 ) { nsum += pImgData[ ( k + m ) * nWidth + p + n ]; ncount++; } } } navg = nsum / ncount; nthres = navg / 10; if ( abs( pImgData[ k * nWidth + p ] - navg ) > nthres ) { pMap[ k * nWidth + p ] = 65535; bcount++; } } } } //FILE *f1; //f1=fopen("D:\\my study\\program\\grid suppression image\\careray1500p test\\badmap.raw","wb"); // // fwrite( pMap, sizeof(unsigned short), nHeight * nWidth, f1); // fclose( f1 ); return true; } /************************************************************************ FUNCTION NAME: DetBadPxlByMF DESCRIPTION: detect bad pixels by 7 * 7 mean filter RETURN VALUE: PARA: [IN] pImageData: primary raw image data array [IN] nWidth: raw image width [IN] nHeight: raw image height [IN] nXOffset: raw image's offset in x direction [IN] nYOffset: raw image's offset in y direction [IN\OUT] pMap: raw image's bad pixel array HISTORY: Aug\23\2010 written by Alex Stocks ************************************************************************/ //bool CPixMatrix::DetBadPxlByMF(ushort_t *pImgData, int nWidth, int nHeight, int nXOffset, int nYOffset, ushort_t *pMap) //{ // if (NULL == pImgData || NULL == pMap // || nWidth <= 0 || nHeight <= 0 // || nXOffset < 0 || nYOffset < 0 // || nWidth <= 2 * nXOffset || nHeight <= 2 * nYOffset) // { // return false; // } // // ////////////////////////////////////////////////////////////////////////// // //step1: detect bad pixels by global threshold // ////////////////////////////////////////////////////////////////////////// // float fGlbAvgPxlValue = CalcGlbAvgPxlValueBySamp(pImgData, nWidth, nHeight, nXOffset, nYOffset); // float fMinThreshold = 0.5f * fGlbAvgPxlValue; // float fMaxThreshold = 1.5f * fGlbAvgPxlValue; // if (65535.0f < fMaxThreshold) //可能是导致16位图像坏点过多判断的原因,16383修改为65535,by陈冠男,2012-12-20 // { // fMaxThreshold = 65535.0f; // } // int nMinXIdx = nXOffset; // int nMaxXIdx = nWidth - nXOffset; // int nMinYIdx = nYOffset; // int nMaxYIdx = nHeight - nYOffset; // int nIdxI = 0; // int nIdxJ = 0; // int nIndex = 0; // // HGLOBAL hMdfPic = ::GlobalAlloc(GHND, nHeight * nWidth * sizeof(ushort_t)); // if (NULL == hMdfPic) // { // ::GlobalUnlock((HGLOBAL)hMdfPic); // return false; // } // ushort_t *pMdfPic = (ushort_t*) ::GlobalLock((HGLOBAL)hMdfPic); // memcpy(pMdfPic, pImgData, nHeight * nWidth * sizeof(ushort_t)); // // //use average pixel value in place of every bad pixel's pixel value // for (nIdxI = nMinYIdx; nIdxI < nMaxYIdx; ++nIdxI) // { // nIndex = nIdxI * nWidth; // for (nIdxJ = nMinXIdx; nIdxJ < nMaxXIdx; ++nIdxJ) // { // if (*(pMap + nIndex + nIdxJ) == 0xFFFF) // { // *(pMdfPic + nIndex + nIdxJ) = (int)fGlbAvgPxlValue; // continue; // } // if (*(pImgData + nIndex + nIdxJ) < fMinThreshold || fMaxThreshold < *(pImgData + nIndex + nIdxJ)) // { // *(pMap + nIndex + nIdxJ) = 0xFFFF; // *(pMdfPic + nIndex + nIdxJ) = (int)fGlbAvgPxlValue; // } // } // } // // ////////////////////////////////////////////////////////////////////////// // //step2: detect bad pixels by mean filter // ////////////////////////////////////////////////////////////////////////// // HGLOBAL hImpPic = ::GlobalAlloc(GHND, nHeight * nWidth * sizeof(ushort_t)); // if (NULL == hImpPic) // { // ::GlobalUnlock(hImpPic); // return false; // } // ushort_t* pImpPic = (ushort_t*) ::GlobalLock(hImpPic); // memcpy(pImpPic, pMdfPic, nHeight * nWidth * sizeof(ushort_t)); // ::GlobalUnlock(hMdfPic); // ::GlobalFree(hMdfPic); // int nAns = Mean7(pImpPic, nWidth, nHeight, nXOffset, nYOffset); // if (nAns < 0) // { // ::GlobalUnlock(hImpPic); // ::GlobalFree(hImpPic); // //::GlobalUnlock(hMdfPic); // //::GlobalFree(hMdfPic); // return false; // } // int nDiff = 0; // float fAbsDiff = fGlbAvgPxlValue * 0.10f; // for (nIdxI = nMinYIdx; nIdxI < nMaxYIdx; ++nIdxI) // { // nIndex = nIdxI * nWidth; // for (nIdxJ = nMinXIdx; nIdxJ < nMaxXIdx; ++nIdxJ) // { // if (*(pMap + nIndex + nIdxJ) != 0xFFFF) // { // nDiff = *(pImgData + nIndex + nIdxJ) - *(pImpPic + nIndex + nIdxJ); // if (fAbsDiff < abs(nDiff)) // { // *(pMap + nIndex + nIdxJ) = 0xFFFF; // } // } // } // } // // ::GlobalUnlock(hImpPic); // ::GlobalFree(hImpPic); // //::GlobalUnlock(hMdfPic); // //::GlobalFree(hMdfPic); // return true; //} int CPixMatrix::BadGridLineCorrect( unsigned short *pImage) { long BadPixNum; long BadNum; memset( m_TempImage, 0, sizeof(unsigned short) * m_nWidth * m_nHeight ); memcpy( m_TempImage, pImage,sizeof(unsigned short) * m_nWidth * m_nHeight ); for ( int i = m_nHOffset + 2; i < m_nHeight - m_nHOffset - 2; i++ ) { m_pBadPixNum = m_BadPixelMap[ i ].bad_pixel_num; if ( m_BadPixelMap[ i ].num_entries > 0 ) { for ( int j = 0; j < m_BadPixelMap[ i ].num_entries; j++ ) { BadPixNum = *m_pBadPixNum++; BadNum = BadPixNum & OFFSET_MASK; if ( BadNum > 1 && BadNum < m_nWidth - 1 ) pImage[ i * m_nWidth + BadNum ] = ( m_TempImage[ ( i - 2 ) * m_nWidth + BadNum - 2 ] + m_TempImage[ ( i - 2 ) * m_nWidth + BadNum ] + m_TempImage[ ( i - 2 ) * m_nWidth + BadNum + 2 ] + m_TempImage[ ( i ) * m_nWidth + BadNum - 2 ] + m_TempImage[ ( i ) * m_nWidth + BadNum + 2 ] + m_TempImage[ ( i + 2 ) * m_nWidth + BadNum - 2 ] + m_TempImage[ ( i + 2 ) * m_nWidth + BadNum ] + m_TempImage[ ( i + 2 ) * m_nWidth + BadNum + 2 ] ) / 8; } } } return 1; }