Пример #1
0
LRESULT CPreviewClientWindow::OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
  CDCHandle dc((HDC) wParam);
  CRect rc;
  COLORREF bgCol = RGB(127, 127, 127);

  if (!m_curOp)
  {
    GetClientRect(&rc);
    dc.FillSolidRect(&rc, bgCol);
  }
  else
  {
    GetClientRect(&rc);
    if (rc.right > ImageWidth())
    {
      rc.left = ImageWidth();
      dc.FillSolidRect(&rc, bgCol);
    }
    
    GetClientRect(&rc);
    if (rc.bottom > ImageHeight())
    {
      rc.top = ImageHeight();
      rc.right = ImageWidth();
      dc.FillSolidRect(&rc, bgCol);
    }
  }
  
  return 1;
}
Пример #2
0
void CPreviewClientWindow::UpdateScrollSize(sBool redraw)
{
  if (!IsWindow())
    return;
  
  frTexture* curTex = getCurrentTex();
  
  if (curTex)
  {
    RECT rc;

    const sInt szx = ImageWidth();
    const sInt szy = ImageHeight();

    GetClientRect(&rc);

    m_scrlMaxX = szx - rc.right;	if (m_scrlMaxX < 0) m_scrlMaxX = 0;
    m_scrlMaxY = szy - rc.bottom; if (m_scrlMaxY < 0) m_scrlMaxY = 0;

    m_scrlX = clamp(m_scrlX, 0, m_scrlMaxX);
    m_scrlY = clamp(m_scrlY, 0, m_scrlMaxY);
  }
  else
  {
    m_scrlX = m_scrlY = 0;
    m_scrlMaxX = m_scrlMaxY = 0;
  }

  if (redraw)
  {
    Invalidate();
    UpdateWindow();
  }
}
Пример #3
0
/***************************************************************
* 函数名称:	TransDoubleJudge
*
* 参数:	IMG			子图像
*			size_t		半径
*			
* 返回值:	存在	true
*			不存在	false
*			
*  
* 功能:	判断是否存在两个边界
*			
*
****************************************************************/
bool CapsuleProc::TransDoubleJudge	(   IMG				&subImage,
										const size_t	radius)
{
	const long areaWidth = 20;
	long centreX = ImageWidth(subImage)/2;
	long centreY = ImageHeight(subImage)/2;
	TArea	area;
	area.X0 = centreX -areaWidth;
	area.X2 = centreX -areaWidth;
	area.X1 = centreX +areaWidth;
	area.Y0 = centreY;
	area.Y2 = centreY-radius;
	area.Y1 = centreY;
	TEdgeResult	tr;
	CFindFirstEdge	(	subImage, 0, m_segmentParam.edgeDensity, 
						area, m_segmentParam.edgeThres, FALSE, tr);
	area.X0 = centreX -areaWidth;
	area.X2 = centreX -areaWidth;
	area.X1 = centreX +areaWidth;
	area.Y0 = centreY;
	area.Y2 = centreY+radius;
	area.Y1 = centreY;
	TEdgeResult downEdge;
	CFindFirstEdge	(	subImage, 0, m_segmentParam.edgeDensity, 
						area, m_segmentParam.edgeThres, FALSE, downEdge);

	if ((tr.y == 0.f)||(downEdge.y == 0.f))
	{
		return true;
	}
	else
	{
		return false;
	}
}
Пример #4
0
// Recognizes a word or group of words, converting to WERD_RES in *words.
// Analogous to classify_word_pass1, but can handle a group of words as well.
void Tesseract::LSTMRecognizeWord(const BLOCK& block, ROW *row, WERD_RES *word,
                                  PointerVector<WERD_RES>* words) {
  TBOX word_box = word->word->bounding_box();
  // Get the word image - no frills.
  if (tessedit_pageseg_mode == PSM_SINGLE_WORD ||
      tessedit_pageseg_mode == PSM_RAW_LINE) {
    // In single word mode, use the whole image without any other row/word
    // interpretation.
    word_box = TBOX(0, 0, ImageWidth(), ImageHeight());
  } else {
    float baseline = row->base_line((word_box.left() + word_box.right()) / 2);
    if (baseline + row->descenders() < word_box.bottom())
      word_box.set_bottom(baseline + row->descenders());
    if (baseline + row->x_height() + row->ascenders() > word_box.top())
      word_box.set_top(baseline + row->x_height() + row->ascenders());
  }
  ImageData* im_data = GetRectImage(word_box, block, kImagePadding, &word_box);
  if (im_data == NULL) return;
  lstm_recognizer_->RecognizeLine(*im_data, true, classify_debug_level > 0,
                                  kWorstDictCertainty / kCertaintyScale,
                                  lstm_use_matrix, &unicharset, word_box, 2.0,
                                  false, words);
  delete im_data;
  SearchWords(words);
}
Пример #5
0
/***************************************************************
*函数名称:	TransSobelAnalysis
*
* 参数:	IMG					图像
*			
*			
* 返回值:	不存在斑点	true, 
*			存在斑点	false
*  
* 功能:	在指定的区域内采用sobel滤波+
*			斑点分析的方法检测是否存在斑点
*
****************************************************************/
bool CapsuleProc::TransSobelAnalysis(IMG	image)
{
	IMG copyImage = 0;
	CreateDuplicateImage (image, copyImage);
	HorizonExtend::Extend(copyImage);
	
	long	width = ImageWidth(copyImage);
	long	height= ImageHeight(copyImage);
	TRect2D<long> roi = TRect2D<long>(TPoint2D<long>(0,0), width, height);
	roi.Expand(-2, -2);
				
	bool success = false;
	IMG		imageROI= NULL;
	CreateImageMap(	copyImage, roi.x0(), roi.y0(), roi.x1(), roi.y1(), roi.Width(), roi.Height(), imageROI);
	if(IsImage(imageROI))
	{
		IMG imageSobel = 0;
		FilterSobelVertical(imageROI, FM_5x5, imageSobel);
		success = RectBlackBlob	(	imageSobel, 
									m_segmentParam.dynWndSize,
									m_segmentParam.dynThres - 2,
									m_segmentParam.blobSize, 
									FBLOB_BORDER_ALL, -1, 4);

		m_sortObserver.ObserverIMG(SortObserver::MSobel, copyImage);
		m_sortObserver.ObserverIMG(SortObserver::CSobel, imageSobel);
		ReleaseImage(imageSobel);
	}
	ReleaseImage(imageROI);
	ReleaseImage(copyImage);
	return success;
}
Пример #6
0
bool CapsuleProc::BlobAnalysis(	IMG		image,
								long    upEdgeY, 
								long    downEdgeY,
							    long	wndSize,
								long	dynThres,
								long	blobSize)
{
	long x0 = 0, y0 =0, dx = 0, dy = 0;
	ProfileBlob(image, ImageWidth(image)/2, m_cvbBlob);
	FBlobGetBoundingBox(m_cvbBlob, 0, x0, y0, dx, dy);
	y0 = 0;
	dy = ImageHeight(image) - 1;
	//中间部分
	TRect2D<long> roi(x0, upEdgeY, x0+dx, downEdgeY);
	roi.Expand		(-10, -6);
	if(false == RectangleBlob(image, roi, wndSize,  dynThres, blobSize, FBLOB_BORDER_ALL, -1, -1, true))
	{	return false;	}

	if (upEdgeY - y0> (y0 + dy) - downEdgeY)
	{
		roi = TRect2D<long>(x0, y0, x0+dx, upEdgeY-15);
		if(false == RectangleBlob(image, roi, wndSize, dynThres, blobSize, FBLOB_BORDER_ALL))
		{	return false;	}		
		
		roi = TRect2D<long>(x0, downEdgeY+15, x0+dx, y0+dy);
		if(false == RectangleBlob(image, roi, wndSize, dynThres+5, blobSize, FBLOB_BORDER_ALL))
		{	return false;	}
	}
	else
	{
		roi= TRect2D<long>(x0, y0, x0+dx, upEdgeY-15);
		if(false == RectangleBlob(image, roi, wndSize, dynThres+5, blobSize, FBLOB_BORDER_ALL))
		{	return false;	}		
		
		roi = TRect2D<long>(x0, downEdgeY+15, x0+dx, y0+dy);
		if(false == RectangleBlob(image, roi, wndSize, dynThres, blobSize, FBLOB_BORDER_ALL))
		{	return false;	}
	}


	
	if (upEdgeY - y0> (y0 + dy) - downEdgeY)
	{
		roi = TRect2D<long>(x0, y0 + (dx/2), x0+dx, upEdgeY-15);
	}
	else
	{
		roi = TRect2D<long>(x0, downEdgeY+15, x0+dx, y0+dy - (dx/2));
	}
	roi.Expand		(-10, -6);
	if(false == RectangleBlob(image, roi, wndSize,  dynThres, blobSize, FBLOB_BORDER_NONE, -1, -1, true))
	{	return false;	}

	return true;
}
Пример #7
0
void Tesseract::reject_edge_blobs(WERD_RES *word) {
  TBOX word_box = word->word->bounding_box();
  // Use the box_word as it is already denormed back to image coordinates.
  int blobcount = word->box_word->length();

  if (word_box.left() < tessedit_image_border ||
      word_box.bottom() < tessedit_image_border ||
      word_box.right() + tessedit_image_border > ImageWidth() - 1 ||
      word_box.top() + tessedit_image_border > ImageHeight() - 1) {
    ASSERT_HOST(word->reject_map.length() == blobcount);
    for (int blobindex = 0; blobindex < blobcount; blobindex++) {
      TBOX blob_box = word->box_word->BlobBox(blobindex);
      if (blob_box.left() < tessedit_image_border ||
          blob_box.bottom() < tessedit_image_border ||
          blob_box.right() + tessedit_image_border > ImageWidth() - 1 ||
          blob_box.top() + tessedit_image_border > ImageHeight() - 1) {
        word->reject_map[blobindex].setrej_edge_char();
        // Close to edge
      }
    }
  }
}
Пример #8
0
bool CapsuleProc::ShrinkHorizontal(	IMG				image, 
									const size_t	shrinkNum)
{
	unsigned char	*pImageBit = NULL;
	PVPAT			VPA = NULL;
	
	GetImageVPA	(image, 0, (void**)&pImageBit, &VPA);
	
	const size_t imageWidth		= ImageWidth (image);
	const size_t imageHeight	= ImageHeight(image);
	const size_t halfWidth		= imageWidth / 2;

	const unsigned char  cstVal	= 127; 
	unsigned char*		 curVal	= 0;

	if (halfWidth < shrinkNum)	{	return false;	}

	for(size_t veCo = 0; veCo < imageHeight; ++veCo)
	{
		for(size_t i = 0; i <= halfWidth; ++i)
		{
			curVal = (VPA[veCo].YEntry + pImageBit + VPA[i].XEntry);
			if ( cstVal == *curVal)	{	*curVal = 0;	}
			else if(0 == *curVal)	{	continue;		}
			else
			{
				for(size_t j = 0; j < shrinkNum; ++j)
				{				
					*(VPA[veCo].YEntry + pImageBit + VPA[j + i].XEntry) = 0;
				}
				break;
			}
		}

		for(size_t i = imageWidth; i >= halfWidth; --i)
		{
			curVal = (VPA[veCo].YEntry + pImageBit + VPA[i].XEntry);
			if (cstVal == *curVal)	{	*curVal = 0;	}
			else if(0 == *curVal)	{	continue;		}
			else
			{
				for(size_t j = 0; j < shrinkNum; ++j)
				{				
					*(VPA[veCo].YEntry + pImageBit + VPA[i - j].XEntry) = 0;
				}
				break;
			}
		}
	}	
	return true;
}
Пример #9
0
/***************************************************************
*函数名称:	ShrinkVertical
*
* 参数:	image			检测图像
*			shrinkNum		纵向缩减的数值
*返回值:	成功	true 
*			失败	false
*  
* 功能:	对胶囊的图像进行纵向的缩减
****************************************************************/
bool CapsuleProc::ShrinkVertical(	IMG				image,
									const size_t	shrinkNum)
{
	unsigned char	*pImageBit = NULL;
	PVPAT			VPA = NULL;
	
	GetImageVPA	(image, 0, (void**)&pImageBit, &VPA);
	
	const size_t imageWidth		= ImageWidth (image);
	const size_t imageHeight	= ImageHeight(image);
	const size_t halfHeight		= imageHeight/2;
	
	if (halfHeight < shrinkNum)		{	return false;	}

	const unsigned char  cstVal	= 127; 
	unsigned char*		 curVal	= 0;

	for(size_t i = 0; i < imageWidth; ++i)
	{
		for(size_t j = 0; j <= halfHeight; ++j)
		{
			curVal = (VPA[i].XEntry + pImageBit + VPA[j].YEntry);
			if (cstVal == *curVal)	{  *curVal = 0;	}
			else if (0 == *curVal)	{	continue;	}
			else
			{
				for(size_t eroCount = 0; eroCount < shrinkNum; ++eroCount)
				{
					*(VPA[i].XEntry + pImageBit + VPA[eroCount + j].YEntry) = 0;
				}
				break;
			}
		}

		for(size_t j = imageHeight - 1; j >= halfHeight; --j)
		{
			curVal = (VPA[i].XEntry + pImageBit + VPA[j].YEntry);
			if (cstVal == *curVal)	{  *curVal = 0;	}
			else if (0 == *curVal)	{	continue;	}
			else
			{
				for(size_t eroCount = 0; eroCount < shrinkNum; ++eroCount)
				{
					*(VPA[i].XEntry + pImageBit + VPA[ j-eroCount].YEntry) = 0;
				}
				break;
			}
		}
	}
	return true;
}
Пример #10
0
/***************************************************************
*函数名称:	FindUpDownEdge
*
* 参数:	image			子图像
*			density			边沿检测的密度
*			threshold		阈值
*			upPos			上边沿
*			downPos			下边沿
*
* 返回值:	成功	true
*			失败	false
*				  
*
* 功能:	得到胶囊套合区的上下边沿的坐标

****************************************************************/
bool CapsuleProc::FindUpDownEdge(	IMG image, long density,double threshold, long &upPos, long &downPos)
{
	long	overX =0, overY =0;
	FindOverlapCenter(image, overX, overY);
	long	roiWidth	= ImageWidth(image)/2;
	long	roiHeight	= ImageHeight(image)/3;
	
	TArea	areaUp		= CreateTArea(overX -roiWidth/2, overY, roiWidth, 	roiHeight);
	long	yUp			= FindFirstEdgeY(image, areaUp, density,threshold);
	
	TArea	areaDown	= CreateTArea(overX -roiWidth/2, overY, roiWidth, 	-roiHeight);
	long	yDown		= FindFirstEdgeY(image, areaDown, density, threshold);
	upPos				= yUp;
	downPos				= yDown;
	return	((upPos != -1) && (downPos != -1));
}
Пример #11
0
bool HorizonExtend::Extend(IMG image)
{
	unsigned char*	pImgBase = NULL; 
	PVPAT			VPAT 	 = NULL; 
	GetImageVPA (image, 0, (LPVOID *)&pImgBase, (PVPAT*)&VPAT); 
	
	long width	= ImageWidth	(image);
	long height = ImageHeight	(image);
	
	for (long y=0; y< height; ++y) 
	{ 
		unsigned char*	pLineAddr = pImgBase + VPAT[y].YEntry; 
		TwoEndInfo endInfo = GetEndInfo(pLineAddr, VPAT, width);
		SetPixelValue(pLineAddr, VPAT, width, endInfo);
	} 
	
	return true;
}
Пример #12
0
bool CapsuleProc::FindOverlapCenter(IMG		rawSubImg,
									long&	centerX,
									long&	centerY)
{
	if(!IsImage(rawSubImg))
	{
		centerX = -1;
		centerY = -1;
		return false;
	}
	
	long width	= ImageWidth (rawSubImg);
	long height = ImageHeight(rawSubImg);
	
	long xc		= width/2;
	long yc0	= height/2 - height/8;
	long yc1	= height/2 + height/8;
	
	double upMean	= 0;
	double downMean = 0;
	
	long offsetX = width/4;
	long offsetY = 5;
	
	TArea upArea = CreateTArea(xc - offsetX,   yc0 + offsetY, 2*offsetX, 2*offsetY);
	
	LMSetImage			(m_lightMeter, rawSubImg);
	LMSetProcessFlag	(m_lightMeter, 0,  TRUE);
	LMSetArea			(m_lightMeter, 0,  upArea);
	LMExecute			(m_lightMeter);
	LMGetStatisticMean	(m_lightMeter, 0, &upMean);
	
	
	TArea downArea = CreateTArea(xc - offsetX, yc1 - offsetY, 2*offsetX, -2*offsetY);
	LMSetImage			(m_lightMeter, rawSubImg);
	LMSetProcessFlag	(m_lightMeter, 0,  TRUE);
	LMSetArea			(m_lightMeter, 0,  downArea);
	LMExecute			(m_lightMeter);
	LMGetStatisticMean	(m_lightMeter, 0, &downMean);
	
	centerX = xc;
	centerY = upMean <= downMean ? yc0 : yc1;
	return true;
}
Пример #13
0
bool CapsuleProc::SobelAnalysis(IMG	image)
{
	IMG copyImage = 0;
	CreateDuplicateImage (image, copyImage);
	HorizonExtend::Extend(copyImage);

	long	width = ImageWidth(copyImage);
	long	height= ImageHeight(copyImage);
	TRect2D<long> roi = TRect2D<long>(TPoint2D<long>(0,0), width, height);
	roi.Expand(-2, -2);
				
	bool success = RectSobelBlob(	copyImage,
					roi,
					m_segmentParam.dynWndSize,
					m_segmentParam.dynThres,
					m_segmentParam.blobSize,
					FBLOB_BORDER_ALL);
	ReleaseImage(copyImage);
	return success;
}
Пример #14
0
	string Driver::GetNextTextElement(string& text,TextStyle& style,int& w,int& h,int maxwidth)
	{
		size_t n=0;
		string ret;

		if(text=="")
			return "";

		// Return blank space as is.
		while(n < text.length() && IsSpace(text[n]) && text[n]!='\n')
			n++;

		if(n)
		{
		}

		// Get a tag if found.
		else if(text[0]=='{')
		{
			while(n < text.length())
				if(text[n]=='}')
				{
					n++;
					break;
				}
				else
					n++;
		}

		// Cut from the next word break.
		else
		{
			while(n < text.length())
				if(text[n]=='.' || text[n]==',' || text[n]==';' || text[n]==':' || text[n]=='!' || text[n]=='?' || text[n]=='\n' || text[n]=='-' || text[n]=='/')
				{
					n++;
					break;
				}
				else if(text[n]=='{' || IsSpace(text[n]))
					break;
				else
					n++;
		}

		// Extract the next element from the text.
		if(n==text.length())
		{
			ret=text;
			text="";
		}
		else
		{
			ret=text.substr(0,n);
			text=text.substr(n);
		}

		w=0;
		h=0;
		// Compute the size for normal text.
		if(ret[0]!='{')
		{
			w=TextWidth(style.font,style.pointsize,ret);

			// Shorten the word if it does not fit.
			while(w > maxwidth && ret.length())
			{
				w-=TextWidth(style.font,style.pointsize,ret.substr(ret.length()-1,1));
				text=ret.substr(ret.length()-1,1)+text;
				ret=ret.substr(0,ret.length()-1);
			}

			h=TextHeight(style.font,style.pointsize,ret);
		}
		// Compute the size for tags.
		else if(ret=="{|}")
		{
			w=3;
			h=TextHeight(style.font,style.pointsize,"|");
		}
		else if(ret=="{hr}")
		{
			w=w-2*style.margin;
			h=1;
		}
		else if(ret=="{lb}")
		{
			w=TextWidth(style.font,style.pointsize,"{");
			h=TextHeight(style.font,style.pointsize,"{");
		}
		else if(ret=="{rb}")
		{
			w=TextWidth(style.font,style.pointsize,"}");
			h=TextHeight(style.font,style.pointsize,"}");
		}
		else if(inlineimage.find(ret)!=inlineimage.end())
		{
			w=ImageWidth(inlineimage[ret]);
			h=ImageHeight(inlineimage[ret]);
		}
		else if(ret.substr(0,3)=="{sz" && ret.substr(ret.length()-1,1)=="}")
		{
			int sz=atoi(ret.substr(3,ret.length()-4).c_str());
			if(sz < 6)
				sz=6;
			else if(sz > 255)
				sz=255;
			style.pointsize=sz;
		}
		else if(ret.substr(0,5)=="{font" && ret.substr(ret.length()-1,1)=="}")
		{
			int n=atoi(ret.substr(5,ret.length()-6).c_str());
			if(n < 0)
				n=0;
			else if(n > 6)
				n=6;
			style.font=n;
		}
		else if(ret.substr(0,5)=="{card" && ret.substr(ret.length()-1,1)=="}")
		{
			int n=atoi(ret.substr(5,ret.length()-6).c_str());
			string name="_unknown_";
			
			if(n >= 0 && n < Database::cards.Cards())
				name=Database::cards.Name(n);
			
			w=TextWidth(style.font,style.pointsize,name);
			h=TextHeight(style.font,style.pointsize,name);
		}
		else if(ret=="{red}")
			style.color=RED;
		else if(ret=="{green}")
			style.color=GREEN;
		else if(ret=="{black}")
			style.color=BLACK;
		else if(ret=="{blue}")
			style.color=BLUE;
		else if(ret=="{yellow}")
			style.color=YELLOW;
		else if(ret=="{white}")
			style.color=WHITE;
		else if(ret=="{brown}")
			style.color=Color(149,79,29);
		else if(ret=="{gold}")
			style.color=Color(205,173,0);
		else if(ret=="{gray}")
			style.color=Color(77,77,77);
		else if(ret=="{magenta}")
			style.color=Color(205,0,205);
		else if(ret=="{orange}")
			style.color=Color(255,127,0);
		else if(ret=="{cyan}")
			style.color=Color(4,197,204);
		else if(ret=="{shadow}")
			style.shadow=true;
		else if(ret=="{noshadow}")
			style.shadow=false;
		else if(ret=="{reset}")
		{
			bool old=style.shadow;
			style=TextStyle();
			style.shadow=old;
		}
          else
          {
               int r=atoi(ret.substr(1).c_str());
               int g=-1;
               int b=-1;
          
               if(r>0 || ret.substr(1,2)=="0,")
               {
				for(size_t n=0; n < ret.length(); n++)
				{
					if(ret[n]==',')
					{
						n++;
						g=atoi(ret.substr(n).c_str());
						for(; n < ret.length(); n++)
							if(ret[n]==',')
							{
								b=atoi(ret.substr(n+1).c_str());
								break;
							}

						break;
					}
				}

				if(r>=0 && g>=0 && b>=0 && r<256 && g<256 && b<256)
				{
					style.color.r=r;
					style.color.g=g;
					style.color.b=b;
				}
			}
		}

		return ret;
	}
Пример #15
0
void WSMSGridder::Invert()
{
	MSData* msDataVector = new MSData[MeasurementSetCount()];
	_hasFrequencies = false;
	for(size_t i=0; i!=MeasurementSetCount(); ++i)
		initializeMeasurementSet(i, msDataVector[i]);
	
	double minW = msDataVector[0].minW;
	double maxW = msDataVector[0].maxW;
	for(size_t i=1; i!=MeasurementSetCount(); ++i)
	{
		if(msDataVector[i].minW < minW) minW = msDataVector[i].minW;
		if(msDataVector[i].maxW > maxW) maxW = msDataVector[i].maxW;
	}
	
	_gridder = std::unique_ptr<WStackingGridder>(new WStackingGridder(_actualInversionWidth, _actualInversionHeight, _actualPixelSizeX, _actualPixelSizeY, _cpuCount, _imageBufferAllocator, AntialiasingKernelSize(), OverSamplingFactor()));
	_gridder->SetGridMode(_gridMode);
	if(_denormalPhaseCentre)
		_gridder->SetDenormalPhaseCentre(_phaseCentreDL, _phaseCentreDM);
	_gridder->SetIsComplex(IsComplex());
	//_imager->SetImageConjugatePart(Polarization() == Polarization::YX && IsComplex());
	_gridder->PrepareWLayers(WGridSize(), double(_memSize)*(7.0/10.0), minW, maxW);
	
	if(Verbose())
	{
		for(size_t i=0; i!=MeasurementSetCount(); ++i)
			countSamplesPerLayer(msDataVector[i]);
	}
	
	_totalWeight = 0.0;
	for(size_t pass=0; pass!=_gridder->NPasses(); ++pass)
	{
		std::cout << "Gridding pass " << pass << "... ";
		if(Verbose()) std::cout << '\n';
		else std::cout << std::flush;
		_inversionWorkLane.reset(new ao::lane<InversionWorkItem>(2048));
		
		_gridder->StartInversionPass(pass);
		
		for(size_t i=0; i!=MeasurementSetCount(); ++i)
		{
			_inversionWorkLane->clear();
			
			MSData& msData = msDataVector[i];
			
			const MultiBandData selectedBand(msData.SelectedBand());
			
			boost::thread thread(&WSMSGridder::workThreadParallel, this, &selectedBand);
		
			gridMeasurementSet(msData);
			
			_inversionWorkLane->write_end();
			thread.join();
		}
		_inversionWorkLane.reset();
		
		std::cout << "Fourier transforms...\n";
		_gridder->FinishInversionPass();
	}
	
	if(Verbose())
	{
		size_t totalRowsRead = 0, totalMatchingRows = 0;
		for(size_t i=0; i!=MeasurementSetCount(); ++i)
		{
			totalRowsRead += msDataVector[i].totalRowsProcessed;
			totalMatchingRows += msDataVector[i].matchingRows;
		}
		
		std::cout << "Total rows read: " << totalRowsRead;
		if(totalMatchingRows != 0)
			std::cout << " (overhead: " << std::max(0.0, round(totalRowsRead * 100.0 / totalMatchingRows - 100.0)) << "%)";
		std::cout << '\n';
	}
	
	if(NormalizeForWeighting())
		_gridder->FinalizeImage(1.0/_totalWeight, false);
	else {
		std::cout << "Not dividing by normalization factor of " << _totalWeight << ".\n";
		_gridder->FinalizeImage(1.0, true);
	}
	
	if(ImageWidth()!=_actualInversionWidth || ImageHeight()!=_actualInversionHeight)
	{
		FFTResampler resampler(_actualInversionWidth, _actualInversionHeight, ImageWidth(), ImageHeight(), _cpuCount);
		
		if(IsComplex())
		{
			double *resizedReal = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight());
			double *resizedImag = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight());
			resampler.Start();
			resampler.AddTask(_gridder->RealImage(), resizedReal);
			resampler.AddTask(_gridder->ImaginaryImage(), resizedImag);
			resampler.Finish();
			_gridder->ReplaceRealImageBuffer(resizedReal);
			_gridder->ReplaceImaginaryImageBuffer(resizedImag);
		}
		else {
			double *resized = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight());
			resampler.RunSingle(_gridder->RealImage(), resized);
			_gridder->ReplaceRealImageBuffer(resized);
		}
	}
	
	delete[] msDataVector;
}
Пример #16
0
void WSMSGridder::initializeMeasurementSet(size_t msIndex, WSMSGridder::MSData& msData)
{
	MSProvider& msProvider = MeasurementSet(msIndex);
	msData.msProvider = &msProvider;
	casacore::MeasurementSet& ms(msProvider.MS());
	if(ms.nrow() == 0) throw std::runtime_error("Table has no rows (no data)");
	
	/**
		* Read some meta data from the measurement set
		*/
	casacore::MSAntenna aTable = ms.antenna();
	size_t antennaCount = aTable.nrow();
	if(antennaCount == 0) throw std::runtime_error("No antennae in set");
	casacore::MPosition::ROScalarColumn antPosColumn(aTable, aTable.columnName(casacore::MSAntennaEnums::POSITION));
	casacore::MPosition ant1Pos = antPosColumn(0);
	
	msData.bandData = MultiBandData(ms.spectralWindow(), ms.dataDescription());
	if(Selection(msIndex).HasChannelRange())
	{
		msData.startChannel = Selection(msIndex).ChannelRangeStart();
		msData.endChannel = Selection(msIndex).ChannelRangeEnd();
		std::cout << "Selected channels: " << msData.startChannel << '-' << msData.endChannel << '\n';
		const BandData& firstBand = msData.bandData.FirstBand();
		if(msData.startChannel >= firstBand.ChannelCount() || msData.endChannel > firstBand.ChannelCount()
			|| msData.startChannel == msData.endChannel)
		{
			std::ostringstream str;
			str << "An invalid channel range was specified! Measurement set only has " << firstBand.ChannelCount() << " channels, requested imaging range is " << msData.startChannel << " -- " << msData.endChannel << '.';
			throw std::runtime_error(str.str());
		}
	}
	else {
		msData.startChannel = 0;
		msData.endChannel = msData.bandData.FirstBand().ChannelCount();
	}
	casacore::MEpoch::ROScalarColumn timeColumn(ms, ms.columnName(casacore::MSMainEnums::TIME));
	const MultiBandData selectedBand = msData.SelectedBand();
	if(_hasFrequencies)
	{
		_freqLow = std::min(_freqLow, selectedBand.LowestFrequency());
		_freqHigh = std::max(_freqHigh, selectedBand.HighestFrequency());
		_bandStart = std::min(_bandStart, selectedBand.BandStart());
		_bandEnd = std::max(_bandEnd, selectedBand.BandEnd());
		_startTime = std::min(_startTime, msProvider.StartTime());
	} else {
		_freqLow = selectedBand.LowestFrequency();
		_freqHigh = selectedBand.HighestFrequency();
		_bandStart = selectedBand.BandStart();
		_bandEnd = selectedBand.BandEnd();
		_startTime = msProvider.StartTime();
		_hasFrequencies = true;
	}
	
	casacore::MSField fTable(ms.field());
	casacore::MDirection::ROScalarColumn phaseDirColumn(fTable, fTable.columnName(casacore::MSFieldEnums::PHASE_DIR));
	casacore::MDirection phaseDir = phaseDirColumn(Selection(msIndex).FieldId());
	casacore::MEpoch curtime = timeColumn(0);
	casacore::MeasFrame frame(ant1Pos, curtime);
	casacore::MDirection::Ref j2000Ref(casacore::MDirection::J2000, frame);
	casacore::MDirection j2000 = casacore::MDirection::Convert(phaseDir, j2000Ref)();
	casacore::Vector<casacore::Double> j2000Val = j2000.getValue().get();
	_phaseCentreRA = j2000Val[0];
	_phaseCentreDec = j2000Val[1];
	if(fTable.keywordSet().isDefined("WSCLEAN_DL"))
		_phaseCentreDL = fTable.keywordSet().asDouble(casacore::RecordFieldId("WSCLEAN_DL"));
	else _phaseCentreDL = 0.0;
	if(fTable.keywordSet().isDefined("WSCLEAN_DM"))
		_phaseCentreDM = fTable.keywordSet().asDouble(casacore::RecordFieldId("WSCLEAN_DM"));
	else _phaseCentreDM = 0.0;

	_denormalPhaseCentre = _phaseCentreDL != 0.0 || _phaseCentreDM != 0.0;
	if(_denormalPhaseCentre)
		std::cout << "Set has denormal phase centre: dl=" << _phaseCentreDL << ", dm=" << _phaseCentreDM << '\n';
	
	std::cout << "Determining min and max w & theoretical beam size... " << std::flush;
	msData.maxW = 0.0;
	msData.minW = 1e100;
	double maxBaseline = 0.0;
	std::vector<float> weightArray(selectedBand.MaxChannels());
	msProvider.Reset();
	while(msProvider.CurrentRowAvailable())
	{
		size_t dataDescId;
		double uInM, vInM, wInM;
		msProvider.ReadMeta(uInM, vInM, wInM, dataDescId);
		const BandData& curBand = selectedBand[dataDescId];
		double wHi = fabs(wInM / curBand.SmallestWavelength());
		double wLo = fabs(wInM / curBand.LongestWavelength());
		double baselineInM = sqrt(uInM*uInM + vInM*vInM + wInM*wInM);
		double halfWidth = 0.5*ImageWidth(), halfHeight = 0.5*ImageHeight();
		if(wHi > msData.maxW || wLo < msData.minW || baselineInM / curBand.SmallestWavelength() > maxBaseline)
		{
			msProvider.ReadWeights(weightArray.data());
			const float* weightPtr = weightArray.data();
			for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch)
			{
				if(*weightPtr != 0.0)
				{
					const double wavelength = curBand.ChannelWavelength(ch);
					double
						uInL = uInM/wavelength, vInL = vInM/wavelength,
						wInL = wInM/wavelength,
						x = uInL * PixelSizeX() * ImageWidth(),
						y = vInL * PixelSizeY() * ImageHeight(),
						imagingWeight = this->PrecalculatedWeightInfo()->GetWeight(uInL, vInL);
					if(imagingWeight != 0.0)
					{
						if(floor(x) > -halfWidth  && ceil(x) < halfWidth &&
							floor(y) > -halfHeight && ceil(y) < halfHeight)
						{
							msData.maxW = std::max(msData.maxW, fabs(wInL));
							msData.minW = std::min(msData.minW, fabs(wInL));
							maxBaseline = std::max(maxBaseline, baselineInM / wavelength);
						}
					}
				}
				++weightPtr;
			}
		}
		
		msProvider.NextRow();
	}
	if(msData.minW == 1e100)
	{
		msData.minW = 0.0;
		msData.maxW = 0.0;
	}
	_beamSize = 1.0 / maxBaseline;
	std::cout << "DONE (w=[" << msData.minW << ":" << msData.maxW << "] lambdas, maxuvw=" << maxBaseline << " lambda, beam=" << Angle::ToNiceString(_beamSize) << ")\n";
	if(HasWLimit()) {
		msData.maxW *= (1.0 - WLimit());
		if(msData.maxW < msData.minW) msData.maxW = msData.minW;
	}

	_actualInversionWidth = ImageWidth();
	_actualInversionHeight = ImageHeight();
	_actualPixelSizeX = PixelSizeX();
	_actualPixelSizeY = PixelSizeY();
	
	if(SmallInversion())
	{
		double totalWidth = _actualInversionWidth * _actualPixelSizeX, totalHeight = _actualInversionHeight * _actualPixelSizeY;
		// Calc min res based on Nyquist sampling rate
		size_t minResX = size_t(ceil(totalWidth*2 / _beamSize));
		if(minResX%4 != 0) minResX += 4 - (minResX%4);
		size_t minResY = size_t(ceil(totalHeight*2 / _beamSize));
		if(minResY%4 != 0) minResY += 4 - (minResY%4);
		if(minResX < _actualInversionWidth || minResY < _actualInversionHeight)
		{
			_actualInversionWidth = std::max(std::min(minResX, _actualInversionWidth), size_t(32));
			_actualInversionHeight = std::max(std::min(minResY, _actualInversionHeight), size_t(32));
			std::cout << "Setting small inversion image size of " << _actualInversionWidth << " x " << _actualInversionHeight << "\n";
			_actualPixelSizeX = totalWidth / _actualInversionWidth;
			_actualPixelSizeY = totalHeight / _actualInversionHeight;
		}
		else {
			std::cout << "Small inversion enabled, but inversion resolution already smaller than beam size: not using optimization.\n";
		}
	}
	
	if(Verbose() || !HasWGridSize())
	{
		double
			maxL = ImageWidth() * PixelSizeX() * 0.5 + fabs(_phaseCentreDL),
			maxM = ImageHeight() * PixelSizeY() * 0.5 + fabs(_phaseCentreDM),
			lmSq = maxL * maxL + maxM * maxM;
		double cMinW = IsComplex() ? -msData.maxW : msData.minW;
		double radiansForAllLayers;
		if(lmSq < 1.0)
			radiansForAllLayers = 2 * M_PI * (msData.maxW - cMinW) * (1.0 - sqrt(1.0 - lmSq));
		else
			radiansForAllLayers = 2 * M_PI * (msData.maxW - cMinW);
		size_t suggestedGridSize = size_t(ceil(radiansForAllLayers));
		if(suggestedGridSize == 0) suggestedGridSize = 1;
		if(suggestedGridSize < _cpuCount)
		{
			// When nwlayers is lower than the nr of cores, we cannot parallellize well. 
			// However, we don't want extra w-layers if we are low on mem, as that might slow down the process
			double memoryRequired = double(_cpuCount) * double(sizeof(double))*double(_actualInversionWidth*_actualInversionHeight);
			if(4.0 * memoryRequired < double(_memSize))
			{
				std::cout <<
					"The theoretically suggested number of w-layers (" << suggestedGridSize << ") is less than the number of availables\n"
					"cores (" << _cpuCount << "). Changing suggested number of w-layers to " << _cpuCount << ".\n";
				suggestedGridSize = _cpuCount;
			}
			else {
				std::cout <<
					"The theoretically suggested number of w-layers (" << suggestedGridSize << ") is less than the number of availables\n"
					"cores (" << _cpuCount << "), but there is not enough memory available to increase the number of w-layers.\n"
					"Not all cores can be used efficiently.\n";
			}
		}
		if(Verbose())
			std::cout << "Suggested number of w-layers: " << ceil(suggestedGridSize) << '\n';
		if(!HasWGridSize())
			SetWGridSize(suggestedGridSize);
	}
}
Пример #17
0
void WSMSGridder::Predict(double* real, double* imaginary)
{
	if(imaginary==0 && IsComplex())
		throw std::runtime_error("Missing imaginary in complex prediction");
	if(imaginary!=0 && !IsComplex())
		throw std::runtime_error("Imaginary specified in non-complex prediction");
	
	MSData* msDataVector = new MSData[MeasurementSetCount()];
	_hasFrequencies = false;
	for(size_t i=0; i!=MeasurementSetCount(); ++i)
		initializeMeasurementSet(i, msDataVector[i]);
	
	double minW = msDataVector[0].minW;
	double maxW = msDataVector[0].maxW;
	for(size_t i=1; i!=MeasurementSetCount(); ++i)
	{
		if(msDataVector[i].minW < minW) minW = msDataVector[i].minW;
		if(msDataVector[i].maxW > maxW) maxW = msDataVector[i].maxW;
	}
	
	_gridder = std::unique_ptr<WStackingGridder>(new WStackingGridder(_actualInversionWidth, _actualInversionHeight, _actualPixelSizeX, _actualPixelSizeY, _cpuCount, _imageBufferAllocator, AntialiasingKernelSize(), OverSamplingFactor()));
	_gridder->SetGridMode(_gridMode);
	if(_denormalPhaseCentre)
		_gridder->SetDenormalPhaseCentre(_phaseCentreDL, _phaseCentreDM);
	_gridder->SetIsComplex(IsComplex());
	//_imager->SetImageConjugatePart(Polarization() == Polarization::YX && IsComplex());
	_gridder->PrepareWLayers(WGridSize(), double(_memSize)*(7.0/10.0), minW, maxW);
	
	if(Verbose())
	{
		for(size_t i=0; i!=MeasurementSetCount(); ++i)
			countSamplesPerLayer(msDataVector[i]);
	}
	
	double *resizedReal = 0, *resizedImag = 0;
	if(ImageWidth()!=_actualInversionWidth || ImageHeight()!=_actualInversionHeight)
	{
		FFTResampler resampler(ImageWidth(), ImageHeight(), _actualInversionWidth, _actualInversionHeight, _cpuCount);
		
		if(imaginary == 0)
		{
			resizedReal = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight());
			resampler.RunSingle(real, resizedReal);
			real = resizedReal;
		}
		else {
			resizedReal = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight());
			resizedImag = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight());
			resampler.Start();
			resampler.AddTask(real, resizedReal);
			resampler.AddTask(imaginary, resizedImag);
			resampler.Finish();
			real = resizedReal;
			imaginary = resizedImag;
		}
	}
	
	for(size_t pass=0; pass!=_gridder->NPasses(); ++pass)
	{
		std::cout << "Fourier transforms for pass " << pass << "... ";
		if(Verbose()) std::cout << '\n';
		else std::cout << std::flush;
		if(imaginary == 0)
			_gridder->InitializePrediction(real);
		else
			_gridder->InitializePrediction(real, imaginary);
		
		_gridder->StartPredictionPass(pass);
		
		std::cout << "Predicting...\n";
		for(size_t i=0; i!=MeasurementSetCount(); ++i)
			predictMeasurementSet(msDataVector[i]);
	}
	
	if(ImageWidth()!=_actualInversionWidth || ImageHeight()!=_actualInversionHeight)
	{
		_imageBufferAllocator->Free(resizedReal);
		_imageBufferAllocator->Free(resizedImag);
	}
	
	size_t totalRowsWritten = 0, totalMatchingRows = 0;
	for(size_t i=0; i!=MeasurementSetCount(); ++i)
	{
		totalRowsWritten += msDataVector[i].totalRowsProcessed;
		totalMatchingRows += msDataVector[i].matchingRows;
	}
	
	std::cout << "Total rows written: " << totalRowsWritten;
	if(totalMatchingRows != 0)
		std::cout << " (overhead: " << std::max(0.0, round(totalRowsWritten * 100.0 / totalMatchingRows - 100.0)) << "%)";
	std::cout << '\n';
	delete[] msDataVector;
}
Пример #18
0
/***************************************************************
*函数名称:	TransProcess
*
* 参数:	无
*			
*			
* 返回值:	unsigned int	处理结果
*			
*  
* 功能:	透明胶囊处理
*			
*
****************************************************************/
unsigned int CapsuleProc::TransProcess( WORKMODE mode )
{
	TTimeDiff td;
	td.Reset();
	
	m_curData.Clear();
	m_sortResult.NewPeriod();
	m_sortObserver.NewPeriod(SortObserver::Mono);
	
	TImgDim dim = Dimension();
	if (!m_transRemain.RemainCapsule(m_rawImage, dim, m_profileImage, m_remainParam, TTransRemain::TRANSMODE))
	{
		OutputDebugString("RemainCapsule Failed!");
		return 0;
	}	

	m_sortObserver.ObserverIMG	(SortObserver::MAll, m_cvbProfileImg);	
	
	long profileBlobCount = 0;
	long minWidth = 1 + m_capsuleParam.capsuleDim.width/8;
	ProfileBlob		(m_cvbProfileImg, minWidth, m_profileBlob);	
	FBlobGetNumBlobs(m_profileBlob, profileBlobCount);	
	
	int counter = 0;
	for(int i = 0; i < profileBlobCount; i++)
	{
		IMG		proSubRot	= NULL;
		size_t  posIndex	= 0;
		if(TransRotateIMG(i, m_profileBlob, m_cvbProfileImg, proSubRot, posIndex))
		{
			if(posIndex ==0 || posIndex == 2)
			{
				counter++;
			}
			m_sortObserver.ObserverIMG(SortObserver::MSub, proSubRot);
			
			const long width = ImageWidth (proSubRot);
			const long height= ImageHeight(proSubRot);
			
			m_curData.WidthAndHeight(width, height);
			
			//all short
			if( IsCapsuleShort(	height, width,
				m_capsuleParam.capsuleDim.height, 
				m_capsuleParam.capsuleDim.tolerance))
			{
				if (REALTIME == mode) 
				{
					m_sortResult.SetResult(SortResult::ShortErr, posIndex);
					OutputDebugString("Capsule Short!");
					ReleaseImage(proSubRot);
					continue;
				}
			}

			if (false == TransDoubleJudge(proSubRot, width/2))
			{
				if (REALTIME == mode) 
				{
					m_sortResult.SetResult(SortResult::DoubleEdge, posIndex);
					OutputDebugString("Double Edge!");
					ReleaseImage(proSubRot);
					continue;
				}
			}

			//Is body/cap short
			long  upEdge = 0, downEdge = 0;
			bool findEdge = FindUpDownEdge(	proSubRot, 
												m_segmentParam.edgeDensity, 
												m_segmentParam.edgeThres,
												upEdge, 
												downEdge);
			if (findEdge)
			{
				if (false == TransIsPartShort(height, upEdge, downEdge))
				{
					if (REALTIME == mode) 
					{
						m_sortResult.SetResult(SortResult::PartShort, posIndex);
						OutputDebugString("Part Short!");
						ReleaseImage(proSubRot);
						continue;
					}
				}
			}
			
			//Soble Analysis
			if( false == TransSobelAnalysis(proSubRot))
			{
				if (REALTIME == mode) 
				{
					m_sortResult.SetResult(SortResult::SobelErr, posIndex);
					OutputDebugString("Sobel Edge!");
					ReleaseImage(proSubRot);
					continue;
				}
			}	

			//blobAnalysis
			if(false == TransBlobAnalysis( proSubRot, upEdge, downEdge,
				m_segmentParam.dynWndSize, 
				m_segmentParam.dynThres,
				m_segmentParam.blobSize))
			{
				if (REALTIME == mode) 
				{
					m_sortResult.SetResult(SortResult::BlobErr, posIndex);
					ReleaseImage(proSubRot);
					OutputDebugString("BlobErr!");
					continue;
				}
			}
			
			ReleaseImage(proSubRot);
		}
	}
	unsigned int badResult = m_sortResult.GetErrorPosition();
	m_sortObserver.ObserverParam(SortObserver::MResult, badResult & 0x0F);
	m_sortObserver.ObserverParam(SortObserver::MTime,	td.msec()		);

	if (mode == REALTIME)
	{
		if( eSecond == m_processIndex )
		{
			CapsuleProc::AddToAllCount( counter );
		}
	}	
	
	if(profileBlobCount > 0)
	{
		RecordingImage();
	}
	return badResult;
}