Exemple #1
0
bool CDetectLine::RunThreshold()
{
	try
	{
		threshold(m_Image, &m_Region, m_minGray, m_maxGray);
		if (HDevWindowStack::IsOpen())
		{
			clear_window(HDevWindowStack::GetActive());
			set_color(HDevWindowStack::GetActive(),"red");
			disp_obj(m_Region, HDevWindowStack::GetActive());

			connection(m_Region, &m_ConnectedRegions);

			//为了设定参数方便,显示面积在m_MinCirleArea/10~m_MaxCirleArea*10(Pixel)的区域面积值
			Hobject selectRegions;
			HTuple RegionCount, Area, Row, Column;
			select_shape(m_ConnectedRegions, &selectRegions, "area", "and", m_minArea/10, m_maxArea*10);
			count_obj(selectRegions, &RegionCount);
			area_center(selectRegions, &Area, &Row, &Column);
			set_color(HDevWindowStack::GetActive(),"blue");
			for (int i=1; i<=RegionCount; i+=1)
			{
				set_tposition(HDevWindowStack::GetActive(), HTuple(Row[i-1]), HTuple(Column[i-1]));
				write_string(HDevWindowStack::GetActive(), Area[i-1].D());
			}
		}
	}
	catch(...)
	{
		AfxMessageBox("二值化失败!");
		return false;
	}

	return true;
}
bool gvVisionImage_botcap_front::_insp_loc( Hobject image_src, Hobject *outRegion_loc)
{
	// Local iconic variables
	Hobject  ImageMean, region_thre, region_fillup;
	Hobject  region_erosion, region_dilation, region_conn, region_sel;

	// Local control variables
	Hlong  numRegions;

	gen_empty_obj(&(*outRegion_loc));

	mean_image(image_src, &ImageMean, 31, 31);
	dyn_threshold(image_src, ImageMean, &region_thre, 5, "light");
	fill_up(region_thre, &region_fillup);
	erosion_circle(region_fillup, &region_erosion, 5.5);
	dilation_circle(region_erosion, &region_dilation, 5.5);
	connection(region_dilation, &region_conn);
	select_shape(region_conn, &region_sel, "area", "and", m_minarea, 999999);
	count_obj(region_sel, &numRegions);

	if ( 1 == numRegions )
	{
		disp_obj(ho_Image,hl_WindowID);
		disp_obj(region_sel,hl_WindowID);
		copy_obj(region_sel, &(*outRegion_loc), 1, 1);
		return true;
	}

	return false;
}
Exemple #3
0
bool CDetectLine::RunSelectTarget()
{
	if(RunThreshold())
	{
		try
		{
			select_shape(m_ConnectedRegions, &m_SelectedRegions, 
				(((((HTuple("area").Append("roundness")).Append("row")).Append("column")).Append("ra")).Append("rb")), "and", 
				(((((HTuple(m_minArea).Append(m_minRectangularity)).Append(m_minRow)).Append(m_minColumn)).Append(m_minRA)).Append(m_minRB)), 
				(((((HTuple(m_maxArea).Append(m_maxRectangularity)).Append(m_maxRow)).Append(m_maxColumn)).Append(m_maxRA)).Append(m_maxRB)));

			fill_up(m_SelectedRegions, &m_RegionFillUp);
			gen_contour_region_xld(m_RegionFillUp, &m_RectangleContours, "border");
			distance_pc(m_RectangleContours, m_ImageHeight/2, m_ImageWidth/2, &m_DistanceMin, &m_DistanceMax);

			if (HDevWindowStack::IsOpen())
			{
				clear_window(HDevWindowStack::GetActive());
				set_color(HDevWindowStack::GetActive(),"red");
				disp_obj(m_RectangleContours, HDevWindowStack::GetActive());

				set_color(HDevWindowStack::GetActive(),"green");
				disp_cross(HDevWindowStack::GetActive(), m_ImageHeight/2, m_ImageWidth/2, 20, 0);
				//disp_cross(HDevWindowStack::GetActive(), m_ImageHeight/2 + m_DistanceMin, m_ImageWidth/2, 20, 0);
			}
			return true;
		}
		catch(...)
		{
			AfxMessageBox("检测直线失败!");
		}
	}

	return false;
}
bool gvVisionTask_black::gvTask_inspect( Hobject image_src, Hobject *outRegion_defects )
{
	// Local iconic variables
	Hobject  TMP_Region, Region1, RegionErosion1,ImageReduced;
	Hobject  Image_meanSmall, Image_meanLarge, RegionDynThresh;
	Hobject  ConnectedRegions, RegionFillUp, RegionErosion, ConnectedRegions1;
	Hobject  SelectedRegions, RegionDilation1, RegionDilation;
	Hobject  RegionDifference, obj_selected;


	// Local control variables
	HTuple  Meancenter, Deviation, Meanouter, Deviation1;
	HTuple  Index, Number;

//	reduce_domain(image_src, gvTask_GetROI()->gvROI_GetROI(), &ImageReduced);
	reduce_domain(image_src, gvTask_GetROI()->gvROI_GetROI(), &ImageReduced);
	threshold(ImageReduced, &Region1, 100, 255);
	fill_up(Region1, &Region1);
	erosion_circle(Region1, &RegionErosion1, 20);
	mean_image(ImageReduced, &Image_meanSmall, 2, 2);
	mean_image(ImageReduced, &Image_meanLarge, 20, 20);
	dyn_threshold(Image_meanSmall, Image_meanLarge, &RegionDynThresh, 5, "dark");
	connection(RegionDynThresh, &ConnectedRegions);
	fill_up(ConnectedRegions, &RegionFillUp);


	erosion_circle(RegionFillUp, &RegionErosion, 1.5);
	connection(RegionErosion, &ConnectedRegions1);

	select_shape(ConnectedRegions1, &SelectedRegions, "area", "and", m_minBlackSpotArea, 5000);
	dilation_circle(SelectedRegions, &RegionDilation1, 2.5);
	intensity(RegionDilation1, Image_meanSmall, &Meancenter, &Deviation);
	dilation_circle(SelectedRegions, &RegionDilation, 5);
	difference(RegionDilation, SelectedRegions, &RegionDifference);
	intensity(RegionDifference, Image_meanSmall, &Meanouter, &Deviation1);
	gen_empty_obj(&(*outRegion_defects));
	for (Index=0; Index<=(Meancenter.Num())-1; Index+=1)
	{
		select_obj(SelectedRegions, &obj_selected, Index+1);
		if (0 != ((HTuple(Meancenter[Index])-HTuple(Meanouter[Index]))<-30))
		{
		  concat_obj((*outRegion_defects), obj_selected, &(*outRegion_defects));

		}
	}
	count_obj((*outRegion_defects), &Number);
	if(Number>m_maxBlackSpotCnt||Number<m_minBlackSpotCnt )
	{
		return FALSE;
	}
	return TRUE;
}
void CDoProcess::DoProcess(CMData* pData,SubTestResult *testItem)
{	 
	// Local iconic variables 
	Hobject Image=pData->m_Image;
	Hlong m_thred_low1=m_Parameters.m_thred_low1;
	Hlong m_thred_high1=m_Parameters.m_thred_high1;
	Hlong m_thred_low2=m_Parameters.m_thred_low2;
	Hlong m_thred_high2=m_Parameters.m_thred_high2;

	Hlong m_thred;
	/////////
	if (m_thred_low1>m_thred_high1)
	{
		m_thred=m_thred_low1;
		m_thred_low1=m_thred_high1;
		m_thred_high1=m_thred;
	}
	if (m_thred_low2>m_thred_high2)
	{
		m_thred=m_thred_low2;
		m_thred_low2=m_thred_high2;
		m_thred_high2=m_thred;
	}

	///////////////////////////////////////////////////////
	// Local iconic variables 
	Hobject  Region, ConnectedRegions, SelectedRegions;
	Hobject  RegionUnion, RegionFillUp, Contours, Rectangle1;
	Hobject  Rectangle2, ImageReduced1, ImageReduced2, Region1;
	Hobject  Region2, RegionDilation1, RegionErosion1, RegionDilation2;
	Hobject  RegionErosion2;


	// Local control variables 
	HTuple  ModelID,Area;//Row1, Column1, Radius1;
	HTuple  Row11, Column11, Row12, Column12;
	HTuple  Row21, Column21, Row22, Column22;
	////////////////////////////////////////////////////////////
	// Local control variables 
	HTuple  Row;
	HTuple Column;
	// dev_update_off(...); only in hdevelop
	try
	{
		///Row_model_center = 237.659;
		//Column_model_center = 339.212;

		/*gen_circle(&Circle5, Row, Column,m_Parameters.radius_ext);
		gen_circle(&Circle6, Row, Column,m_Parameters.radius_inner);
		difference(Circle5, Circle6, &RegionDifference_median);
		reduce_domain(Image, RegionDifference_median, &ImageReduced_median);
		intensity(RegionDifference_median, Image, &Mean_median, &Deviation_median);
		fast_threshold(ImageReduced_median, &Region_median, m_Parameters.radius_inner_thred, 255, 1);//Mean_median*1.2
		connection(Region_median, &ConnectedRegions_median);
		select_shape(ConnectedRegions_median, &SelectedRegions_median, "area", "and", m_Parameters.radius_ext_extract_size, 
		99999);
		union1(SelectedRegions_median, &RegionUnion_median);
		area_center(RegionUnion_median, &Area_baoChiJia, &Row_baoChiJia, &Column_baoChiJia);*/

		//**********************************************************
		threshold(Image, &Region, 0,  m_Parameters.radius_inner_thred);
		connection(Region, &ConnectedRegions);
		select_shape(ConnectedRegions, &SelectedRegions, "area", "and", m_Parameters.radius_ext_extract_size, 149999);
		union1(SelectedRegions, &RegionUnion);
		fill_up(RegionUnion, &RegionFillUp);
		area_center(RegionFillUp, &Area, &Row, &Column);
		///////////////////////////////////
		/*if (!_access(m_Parameters.CenterOcrModelRegion.c_str(),0))
		{
			wstring msg = _T("Set Region already Exit.OverWrite or Not?");

			if (MessageBox(NULL,msg.c_str(),_T("ReadFile Error"),MB_OK||MB_CANCELTRYCONTINUE)==IDOK)
			{
				write_region(RegionFillUp,m_Parameters.CenterOcrModelRegion.c_str());
			}

		}
		else*/
			write_region(RegionFillUp,m_Parameters.CenterOcrModelRegion.c_str());
		/////////////////////////////////////////
		gen_contour_region_xld(RegionFillUp, &Contours, "border");

		create_shape_model_xld(Contours, 1, -0.69, 0.79, "auto", "auto", "ignore_local_polarity", 
			5, &ModelID);

		//匹配数据

		/*if (!_access(m_Parameters.CenterOcrModelName.c_str(),0))
		{
			wstring msg = _T("Set Model already Exit.OverWrite or Not?");

			if (MessageBox(NULL,msg.c_str(),_T("ReadFile Error"),MB_OK||MB_CANCELTRYCONTINUE)==IDOK)
			{
				write_shape_model(ModelID,m_Parameters.CenterOcrModelName.c_str());
			}

		}
		else*/
			write_shape_model(ModelID,m_Parameters.CenterOcrModelName.c_str());	



		//*****************************************************************
		Row11=m_Parameters.YMin1;
		Row12=m_Parameters.YMin1+m_Parameters.YMax1;
		Column11=m_Parameters.XMin1;
		Column12=m_Parameters.XMin1+m_Parameters.XMax1;
		Row21=m_Parameters.YMin2;
		Row22=m_Parameters.YMin2+m_Parameters.YMax2;
		Column21=m_Parameters.XMin2;
		Column22=m_Parameters.XMin2+m_Parameters.XMax2;
		gen_rectangle1(&Rectangle1, Row11, Column11, Row12, Column12);

		gen_rectangle1(&Rectangle2, Row21, Column21, Row22, Column22);

		reduce_domain(Image, Rectangle1, &ImageReduced1);


		reduce_domain(Image, Rectangle2, &ImageReduced2);


		threshold(ImageReduced1, &Region1, m_Parameters.m_thred_low1, m_Parameters.m_thred_high1);
		threshold(ImageReduced2, &Region2, m_Parameters.m_thred_low2, m_Parameters.m_thred_high2);
		dilation_circle(Region1, &RegionDilation1, 3.5);
		erosion_circle(RegionDilation1, &RegionErosion1, m_Parameters.region_erosion1_size);

		dilation_circle(Region2, &RegionDilation2, 3.5);
		erosion_circle(RegionDilation2, &RegionErosion2, m_Parameters.region_erosion2_size);

		//创建模板时 保存区域和区域图片。在提取区域时,因为正常运行时每次都要用,不能使用
		/*if (!_access(m_Parameters.CenterOcrModelRegion1.c_str(),0))
		{
			wstring msg = _T("Set Region already Exit.OverWrite or Not?");

			if (MessageBox(NULL,msg.c_str(),_T("ReadFile Error"),MB_OK||MB_CANCELTRYCONTINUE)==IDOK)
			{
				write_region(RegionErosion1,m_Parameters.CenterOcrModelRegion1.c_str());
			}

		}
		else*/
			write_region(RegionErosion1,m_Parameters.CenterOcrModelRegion1.c_str());
		/*if (!_access(m_Parameters.CenterOcrModelRegion2.c_str(),0))
		{
			wstring msg = _T("Set Region already Exit.OverWrite or Not?");

			if (MessageBox(NULL,msg.c_str(),_T("ReadFile Error"),MB_OK||MB_CANCELTRYCONTINUE)==IDOK)
			{
				write_region(RegionErosion2,m_Parameters.CenterOcrModelRegion2.c_str());
			}

		}
		else*/
			write_region(RegionErosion2,m_Parameters.CenterOcrModelRegion2.c_str());
		/////////////////////////////////////////////////
		// Number_QiPao=1;
		if (1)
		{

			//pData->m_isFail= false;
			//testItem->m_bFailSubTest = false;
			pData->m_center_y2=Row[0].D();
			pData->m_center_x2=Column[0].D();
		}
		else
		{

			//testItem->m_ErrorMsg = "Error No Find Center";
			//testItem->m_ErrorY = 250;
			//testItem->m_ErrorX = 350;
			//testItem->m_ErrorR = 55;
			//set_color(pData->m_ShowHWindow,"red");
			//disp_region(SelectedRegions_qiPao_extract,pData->m_ShowHWindow);
			//disp_circle(pData->m_ShowHWindow,Row_center,Column_center,85);
		}
		set_color(pData->m_ShowHWindow,"blue");
		disp_obj(Contours,pData->m_ShowHWindow);
		set_color(pData->m_ShowHWindow,"green");
		disp_region(Rectangle1,pData->m_ShowHWindow);
		disp_region(Rectangle2,pData->m_ShowHWindow);
		disp_region(RegionErosion1,pData->m_ShowHWindow);
		disp_region(RegionErosion2,pData->m_ShowHWindow);
		set_color(pData->m_ShowHWindow,"red");
		///////

	}
	catch (HException &except) 
	{
		pData->m_isFail = true;
		testItem->m_bFailSubTest = true;
		pData->m_orientationPhi=0;
		//testItem->m_ErrorMsg = except.file;
		//testItem->m_ErrorMsg += " ";
		//testItem->m_ErrorMsg += except.line;
		//testItem->m_ErrorMsg += " ";
		//testItem->m_ErrorMsg += except.message;
		testItem->m_ErrorY = 1;
		testItem->m_ErrorX = 1;
		testItem->m_ErrorR = 4;
	}
}
Exemple #6
0
void CDoProcess::DoProcess(CMData* pData,SubTestResult *testItem)
{	

	try
	{

		Hobject image = pData->m_Image;
		Hobject  ROI,Circle1,Circle2;

		if((pData->r_real+m_Parameters.Regional_Out-m_Parameters.ROIWidth)>0)
		{
			gen_circle(&Circle1, (pData->m_center_y), (pData->m_center_x), (pData->r_real+m_Parameters.Regional_Out));
			gen_circle(&Circle2, (pData->m_center_y), (pData->m_center_x), pData->r_real+m_Parameters.Regional_Out-m_Parameters.ROIWidth);
			difference(Circle1, Circle2, &ROI);

			if (ShowObject&&pData->m_isDebug)
			{
				set_color(pData->m_ShowHWindow,"blue");	
				disp_obj(Circle1,pData->m_ShowHWindow);
				set_color(pData->m_ShowHWindow,"green");	
				disp_obj(Circle2,pData->m_ShowHWindow);
			}

		}
		else
		{
			gen_circle(&ROI, (pData->m_center_y), (pData->m_center_x), (pData->r_real+m_Parameters.Regional_Out));

			if (ShowObject&&pData->m_isDebug)
			{
				set_color(pData->m_ShowHWindow,"blue");	
				disp_obj(ROI,pData->m_ShowHWindow);
			}
		}



  // Local iconic variables 
  Hobject  region_tai,BlackImageMean,WhiteImageMean;
  Hobject  BlackPointDynThresh, BLACK_POINT, SeriousBlackPointDynThresh;
  Hobject  SeriousBlackConnected, SERIOUS_BlackPoint;
  Hobject  WhitePointDynThresh, WHITE_POINT, SeriousWhitePointDynThresh;
  Hobject  SeriousWhiteConnected, SERIOUS_WhitePoint;
  Hlong  Number;
  Hobject  Dilation,ExpandedImage;

  	reduce_domain(image, ROI, &region_tai);
	expand_domain_gray(region_tai, &ExpandedImage, 2);
	reduce_domain(ExpandedImage, ROI, &region_tai);
  //*===================================================================
  //*找黑色划痕与污点
  mean_image(region_tai, &BlackImageMean, m_Parameters.BlackMaskSize, m_Parameters.BlackMaskSize);

  //*找大范围黑缺陷,适用于缺陷浅以及数量比较多的情况,参数越细,误报越高
  dyn_threshold(region_tai, BlackImageMean, &BlackPointDynThresh,m_Parameters.BlackPointDynThresh, "dark");
  select_shape(BlackPointDynThresh, &BLACK_POINT, "area", "and", m_Parameters.BlackPointSize, 99999);
  count_obj(BLACK_POINT, &Number);
  if (Number)
  {
	  //pData->m_ErrorRegist = BLACK_POINT;
	  pData->m_isFail =true;
	  testItem->m_bFailSubTest = true;
	  //testItem->m_ErrorMsg = "BlackPoint error";
	  //return;
	  if (pData->m_isDebug)
	  {
		  dilation_circle(BLACK_POINT,&Dilation,2.5);
		  set_color(pData->m_ShowHWindow,"red");
		  disp_obj(Dilation,pData->m_ShowHWindow);
	  }
  }
  //*找单一块极黑缺陷,适用于伤的比较深,污点比较黑的情况
  dyn_threshold(region_tai, BlackImageMean, &SeriousBlackPointDynThresh,m_Parameters.SeriousBlackPointDynThresh, "dark");
  connection(SeriousBlackPointDynThresh, &SeriousBlackConnected);
  select_shape(SeriousBlackConnected, &SERIOUS_BlackPoint, "area", "and",m_Parameters.SeriousBlackPointSize, 99999);
  count_obj(SERIOUS_BlackPoint, &Number);
  if (Number)
  {
	  pData->m_isFail =true;
	  testItem->m_bFailSubTest = true;
	  if (pData->m_isDebug)
	  {
		  dilation_circle(SERIOUS_BlackPoint,&Dilation,2.5);
		  set_color(pData->m_ShowHWindow,"red");
		  disp_obj(Dilation,pData->m_ShowHWindow);
	  }
  }
  //*===================================================================
  //*找白色划痕与污点
  mean_image(region_tai, &WhiteImageMean, m_Parameters.WhiteMaskSize, m_Parameters.WhiteMaskSize);

  //*找大范围白缺陷
  dyn_threshold(region_tai, WhiteImageMean, &WhitePointDynThresh, m_Parameters.WhitePointDynThresh, "light");
  select_shape(WhitePointDynThresh, &WHITE_POINT, "area", "and", m_Parameters.WhitePointSize, 99999);
  count_obj(WHITE_POINT, &Number);
  if (Number)
  {
	  //pData->m_ErrorRegist = WHITE_POINT;
	  pData->m_isFail =true;
	  testItem->m_bFailSubTest = true;
	  //testItem->m_ErrorMsg = "WhitePoint error";
	  if (pData->m_isDebug)
	  {
		  dilation_circle(WHITE_POINT,&Dilation,2.5);
		  set_color(pData->m_ShowHWindow,"yellow");
		  disp_obj(Dilation,pData->m_ShowHWindow);
	  }
  }
  //*找单一块极白污点

  dyn_threshold(region_tai, WhiteImageMean, &SeriousWhitePointDynThresh, m_Parameters.SeriousWhitePointDynThresh, "light");
  connection(SeriousWhitePointDynThresh, &SeriousWhiteConnected);
  select_shape(SeriousWhiteConnected, &SERIOUS_WhitePoint, "area", "and",m_Parameters.SeriousWhitePointSize, 99999);
  count_obj(SERIOUS_WhitePoint, &Number);
  if (Number)
  {
	  //pData->m_ErrorRegist = SERIOUS_WhitePoint;
	  pData->m_isFail =true;
	  testItem->m_bFailSubTest = true;
	  //testItem->m_ErrorMsg = "SeriousWhitePoint error";
	  if (pData->m_isDebug)
	  {
		  dilation_circle(SERIOUS_WhitePoint,&Dilation,2.5);
		  set_color(pData->m_ShowHWindow,"yellow");
		  disp_obj(Dilation,pData->m_ShowHWindow);
	  }
  }

  Hobject RegionUnionBlack,RegionUnionWhite,RegionUnionWhole;

  union2(BLACK_POINT, SERIOUS_BlackPoint, &RegionUnionBlack);
  union2(WHITE_POINT, SERIOUS_WhitePoint, &RegionUnionWhite);
  union2(RegionUnionBlack, RegionUnionWhite, &RegionUnionWhole);
  //dilation_circle(RegionUnionWhole, &RegionDilation, 2.5);
  union2(RegionUnionWhole, pData->m_ErrorRegist, &RegionUnionWhole);
  pData->m_ErrorRegist=RegionUnionWhole;

}
	catch (HException &except) 
	
	{
		if (pData->m_isDebug)
		{
			set_color(pData->m_ShowHWindow,"green");
			set_tposition( pData->m_ShowHWindow,25, 145);
			#ifdef _ENGLISH
						write_string(pData->m_ShowHWindow,"DynThreshed1.3 parameter values error,please re-adjust");
			#else
						write_string(pData->m_ShowHWindow,"DynThreshed1.3程序参数值出错,请重新调节参数");
			#endif

		}
		pData->m_isFail = true;
		testItem->m_bFailSubTest = true;
	}

}
Exemple #7
0
void CDoProcess::DoProcess(CMData* pData,SubTestResult *testItem)
{	
	try
	{

	Hobject   FindImage,ImageReduced,EllipseObj;
	Hobject  ModelRegions, ConnectedRegions, SelectedRegions,ModelImages,SelectedRegionsSize,RegionClosing,RegionUnion,RegionFillUp,RegionOpening;
	Hlong Contrast = m_Parameters.m_Contrast;


	HTuple Row2, Column2, Radius2;

	Hobject regional_Internal,regional_Out;


	get_image_size (pData->m_Image, &Column2, &Row2);
	gen_ellipse(&EllipseObj, Row2/2, Column2/2, 0, m_Parameters.LongAxis, m_Parameters.ShortAxis);
	if (ShowObject&&pData->m_isDebug)
	{
		set_color(pData->m_ShowHWindow,"yellow");	
		disp_obj(EllipseObj,pData->m_ShowHWindow);
	}
	reduce_domain(pData->m_Image, EllipseObj, &ImageReduced);
	inspect_shape_model(ImageReduced, &ModelImages, &ModelRegions, 1, Contrast);
	connection(ModelRegions, &ConnectedRegions);
	//**==============================================================
	//	**选择区域这条更改,原来默认是700,现在我想改成可调的,我现在就设的40
	select_shape(ConnectedRegions, &SelectedRegionsSize, "area", "and", m_Parameters.Select_Shape_Size, 99999);

	//	** 添加这句union1
	closing_circle (SelectedRegionsSize, &RegionClosing, 400.5);
	union1(RegionClosing, &RegionUnion);

	fill_up (RegionUnion, &RegionFillUp);
    opening_circle (RegionFillUp, &RegionOpening, m_Parameters.OutlierRemover+0.5);

	Hlong TempNumber;		  

	count_obj(RegionOpening,&TempNumber);

	  if (TempNumber<1)
	  {  
		  pData->m_isFail = true;
		  testItem->m_bFailSubTest = true;

		  if (pData->m_isDebug)
		  {
			  set_color(pData->m_ShowHWindow,"green");
			  set_tposition( pData->m_ShowHWindow,120, 0);
			#ifdef _ENGLISH
						  write_string(pData->m_ShowHWindow,"Shell center not found");
			#else
						  write_string(pData->m_ShowHWindow,"圆中心未找到");
			#endif
		  }
		  //pData->m_center_x=50;
		  //pData->m_center_y=50;
		  //pData->r_real=40;
		  //return;
	  }
		  
	//*==============================================================
	double  CenterRow, CenterColumn, CenterRadius;
	smallest_circle(RegionOpening, &CenterRow, &CenterColumn, &CenterRadius);


		  Hobject circle;
		  if ((m_Parameters.XMin<CenterColumn)&&(CenterColumn<m_Parameters.XMax)&&(m_Parameters.YMin<CenterRow)&&(CenterRow<m_Parameters.YMax)&&(CenterRadius<m_Parameters.RMax)&&(CenterRadius>m_Parameters.RMin))
		  {
			  pData->m_center_x=CenterColumn;
			  pData->m_center_y=CenterRow;
			  pData->r_real=CenterRadius;
			  set_color(pData->m_ShowHWindow,"cyan");
			  gen_circle(&circle, pData->m_center_y, pData->m_center_x, pData->r_real);
			  disp_obj(circle,pData->m_ShowHWindow);
		  }
		  else
		  {
			  pData->m_isFail = true;
			  testItem->m_bFailSubTest = true;
			  pData->m_center_x=50;
			  pData->m_center_y=50;
			  pData->r_real=40;
			  set_color(pData->m_ShowHWindow,"red");
			  gen_circle(&circle, pData->m_center_y, pData->m_center_x, pData->r_real);
			  disp_obj(circle,pData->m_ShowHWindow);

			  if (pData->m_isDebug)
			  {
					  set_color(pData->m_ShowHWindow,"green");
					  set_tposition( pData->m_ShowHWindow,5, 145);
					#ifdef _ENGLISH
						write_string(pData->m_ShowHWindow,"Fitted shell center not match the qualifications");
					#else
						write_string(pData->m_ShowHWindow,"拟合得到的圆的中心坐标及半径与限定条件不符");
					#endif

			  }
			  //return;

		  }

	  //set_color(pData->m_ShowHWindow,"red");
	  //Hobject circle,ContCircle;
	  //gen_circle(&circle, pData->m_center_y, pData->m_center_x, pData->r_real);
	  //disp_obj(circle,pData->m_ShowHWindow);
	}

	catch (HException &except) 
	{

		if (pData->m_isDebug)
		{
			set_color(pData->m_ShowHWindow,"green");
			set_tposition( pData->m_ShowHWindow,25, 145);
			#ifdef _ENGLISH
						write_string(pData->m_ShowHWindow,"CenterHC23 parameter values error,please re-adjust");
			#else
						write_string(pData->m_ShowHWindow,"CenterHC23程序参数值出错,请重新调节参数");
			#endif
		}
		
		pData->m_isFail = true;
		testItem->m_bFailSubTest = true;
		pData->m_center_x=50;
		pData->m_center_y=50;
		pData->r_real=40;

	}

}
void CDoProcess::DoProcess(CMData* pData,SubTestResult *testItem)
{	 
	// Local iconic variables 
	Hobject Image=pData->m_Image;
	Hlong m_contrast_low1=m_Parameters.m_contrast_low;
	Hlong m_contrast_high1=m_Parameters.m_contrast_high;


	Hlong m_thred;
	/////////
	if (m_contrast_low1>m_contrast_high1)
	{
		m_thred=m_contrast_low1;
		m_contrast_low1=m_contrast_high1;
		m_contrast_high1=m_thred;
	}
	if (m_Parameters.radius_inner>m_Parameters.radius_ext)
	{
		m_thred=m_Parameters.radius_inner;
		m_Parameters.radius_inner=m_Parameters.radius_ext;
		m_Parameters.radius_ext=m_thred;
	}
	Hobject  Circle5, Circle6, RegionDifference_median,ModelContours;
	Hobject  ImageReduced_median, Region_median, ConnectedRegions_median;
	Hobject  SelectedRegions_median, RegionUnion_median, ImageReduced_median_extract;
	Hobject  ModelImages, ModelRegions;


	// Local control variables 
	HTuple   Mean_median, Deviation_median;
	HTuple  Area_baoChiJia, Row_baoChiJia, Column_baoChiJia;
	HTuple  ModelID, Row2, Column2, Angle2, Score2;
	// Local control variables 
	HTuple  Row=pData->m_center_y;
	HTuple Column= pData->m_center_x;
	// dev_update_off(...); only in hdevelop
	try
	{
		///Row_model_center = 237.659;
		//Column_model_center = 339.212;

		gen_circle(&Circle5, Row, Column,m_Parameters.radius_ext);
		gen_circle(&Circle6, Row, Column,m_Parameters.radius_inner);
		difference(Circle5, Circle6, &RegionDifference_median);
		reduce_domain(Image, RegionDifference_median, &ImageReduced_median);
		intensity(RegionDifference_median, Image, &Mean_median, &Deviation_median);
		fast_threshold(ImageReduced_median, &Region_median, m_Parameters.radius_inner_thred, 255, 1);//Mean_median*1.2
		connection(Region_median, &ConnectedRegions_median);
		select_shape(ConnectedRegions_median, &SelectedRegions_median, "area", "and", m_Parameters.radius_ext_extract_size, 
			99999);
		union1(SelectedRegions_median, &RegionUnion_median);
		area_center(RegionUnion_median, &Area_baoChiJia, &Row_baoChiJia, &Column_baoChiJia);
		//创建模板时 保存区域和区域图片。在提取区域时,因为正常运行时每次都要用,不能使用
		/*if (!_access(m_Parameters.CenterOcrModelRegion.c_str(),0))
		{
			wstring msg = _T("Set Region already Exit.OverWrite or Not?");

			if (MessageBox(NULL,msg.c_str(),_T("ReadFile Error"),MB_OK||MB_CANCELTRYCONTINUE)==IDOK)
			{
				write_region(RegionUnion_median,m_Parameters.CenterOcrModelRegion.c_str());
			}

		}
		else*/
			write_region(RegionUnion_median,m_Parameters.CenterOcrModelRegion.c_str());

		reduce_domain(Image, RegionUnion_median, &ImageReduced_median_extract);

		//write_image(ImageReduced_median_extract, "bmp", 0, "D:/SLACTST/CH1.101/模板字符区域图片.bmp");
		//
		/*if (!_access(m_Parameters.CenterOcrModelPicture.c_str(),0))
		{
		wstring msg = _T("Set Picture already Exit.OverWrite or Not?");

		if (MessageBox(NULL,msg.c_str(),_T("ReadFile Error"),MB_OK||MB_CANCELTRYCONTINUE)==IDOK)
		{
		write_image(ImageReduced_median_extract, "bmp", 0,m_Parameters.CenterOcrModelPicture.c_str());
		}

		}
		else
		write_image(ImageReduced_median_extract, "bmp", 0,m_Parameters.CenterOcrModelPicture.c_str());	*/
		//匹配数据
		inspect_shape_model(ImageReduced_median_extract, &ModelImages, &ModelRegions, 1, 
			25);
		create_shape_model(ImageReduced_median_extract, 4, 0, HTuple(360).Rad(), "auto", 
			"auto", "use_polarity", m_contrast_high1, m_contrast_low1, &ModelID);
		find_shape_model(Image, ModelID, 0, HTuple(360).Rad(), 0.5, 1, 0.5, "least_squares", 
			0, 0.9, &Row2, &Column2, &Angle2, &Score2);

		/*if (!_access(m_Parameters.CenterOcrModelName.c_str(),0))
		{
			wstring msg = _T("Set Model already Exit.OverWrite or Not?");

			if (MessageBox(NULL,msg.c_str(),_T("ReadFile Error"),MB_OK||MB_CANCELTRYCONTINUE)==IDOK)
			{
				write_shape_model(ModelID,m_Parameters.CenterOcrModelName.c_str());
			}

		}
		else*/
			write_shape_model(ModelID,m_Parameters.CenterOcrModelName.c_str());	
		//*查看模板提取效果
		set_shape_model_origin(ModelID, -Row_baoChiJia, -Column_baoChiJia);
		get_shape_model_contours(&ModelContours, ModelID, 1);
		/////////////////////////////////////////////////*/
		// Number_QiPao=1;
		if (1)
		{

			//pData->m_isFail= false;
			//testItem->m_bFailSubTest = false;
			pData->m_center_y2=Row_baoChiJia[0].D();
			pData->m_center_x2=Column_baoChiJia[0].D();
		}
		else
		{

			//testItem->m_ErrorMsg = "Error No Find Center";
			//testItem->m_ErrorY = 250;
			//testItem->m_ErrorX = 350;
			//testItem->m_ErrorR = 55;
			//set_color(pData->m_ShowHWindow,"red");
			//disp_region(SelectedRegions_qiPao_extract,pData->m_ShowHWindow);
			//disp_circle(pData->m_ShowHWindow,Row_center,Column_center,85);
		}
		set_color(pData->m_ShowHWindow,"blue");
		disp_obj(ModelContours,pData->m_ShowHWindow);
		set_color(pData->m_ShowHWindow,"green");
		disp_region(RegionUnion_median,pData->m_ShowHWindow);
		disp_region(Circle5,pData->m_ShowHWindow);
		disp_region(Circle6,pData->m_ShowHWindow);
		set_color(pData->m_ShowHWindow,"red");
		///////

	}
	catch (HException &except) 
	{
		pData->m_isFail = true;
		testItem->m_bFailSubTest = true;
		pData->m_orientationPhi=0;
		//testItem->m_ErrorMsg = except.file;
		//testItem->m_ErrorMsg += " ";
		//testItem->m_ErrorMsg += except.line;
		//testItem->m_ErrorMsg += " ";
		//testItem->m_ErrorMsg += except.message;
		testItem->m_ErrorY = 1;
		testItem->m_ErrorX = 1;
		testItem->m_ErrorR = 4;
	}
}
void CDoProcess::DoProcess(CMData* pData,SubTestResult *testItem)
{	
	Hlong m_radius_inner=m_Parameters.radius_inner;
	Hlong m_radius_ext=m_Parameters.radius_ext;

	Hlong m_thred;

	// dev_update_off(...); only in hdevelop
	//Hobject Image=pData->m_Image;
	/////////
	if (m_Parameters.radius_inner>m_Parameters.radius_ext)
	{
		m_thred=m_Parameters.radius_inner;
		m_Parameters.radius_inner=m_Parameters.radius_ext;
		m_Parameters.radius_ext=m_thred;
	}
	if (m_Parameters.radius_inner2>m_Parameters.radius_ext2)
	{
		m_thred=m_Parameters.radius_inner2;
		m_Parameters.radius_inner2=m_Parameters.radius_ext2;
		m_Parameters.radius_ext2=m_thred;
	}
  // Local iconic variables 
  Hobject Image=pData->m_Image;
  // Local iconic variables 
  Hobject   Circle1, Circle2, RegionDifference_ext;
  Hobject  Circle3, Circle4, RegionDifference_inner, ImageReduced_ext;
  Hobject  ImageReduced_inner, ImageEmphasize_inner, ImageEmphasize_ext;
  Hobject  Region_ext, Region_inner, RegionUnion, ConnectedRegions;
  Hobject  SelectedRegions;


  // Local control variables 
  HTuple   Mean_ext, Deviation_ext;
  HTuple  Mean_inner, Deviation_inner, Number;



  // Local control variables 
  try
  {

	   HTuple  Row=pData->m_center_y;
	  HTuple Column= pData->m_center_x;
	  if (pData->m_isFail )
	  {
	  Row=250;
	  Column=330;
	  }
	  gen_circle(&Circle1, Row, Column, m_Parameters.radius_ext);
	  gen_circle(&Circle2, Row, Column, m_Parameters.radius_inner);
	  difference(Circle1, Circle2, &RegionDifference_ext);
	  gen_circle(&Circle3, Row, Column,m_Parameters.radius_ext2);
	  gen_circle(&Circle4, Row, Column, m_Parameters.radius_inner2);
	  difference(Circle3, Circle4, &RegionDifference_inner);
	  //////////////////////////
	  set_color(pData->m_ShowHWindow,"green");
	  disp_region(Circle1,pData->m_ShowHWindow);
	  disp_region(Circle2,pData->m_ShowHWindow);
	  disp_region(Circle3,pData->m_ShowHWindow);
	  disp_region(Circle4,pData->m_ShowHWindow);
	  set_color(pData->m_ShowHWindow,"red");
	  ///////////////////////////////
	  reduce_domain(Image, RegionDifference_ext, &ImageReduced_ext);
	  reduce_domain(Image, RegionDifference_inner, &ImageReduced_inner);

	  //*端面检测**************

	  emphasize(ImageReduced_inner, &ImageEmphasize_inner, m_Parameters.radius_ext_empha_size, m_Parameters.radius_ext_empha_size, m_Parameters.radius_inner2_enhance);
	  emphasize(ImageReduced_ext, &ImageEmphasize_ext, m_Parameters.radius_ext_empha_size, m_Parameters.radius_ext_empha_size, m_Parameters.radius_inner2_enhance);

	  intensity(RegionDifference_ext, Image, &Mean_ext, &Deviation_ext);
	  intensity(RegionDifference_inner, Image, &Mean_inner, &Deviation_inner);
	  threshold(ImageEmphasize_ext, &Region_ext, 0,m_Parameters.radius_ext2_thred );//Mean_ext-30
	  fast_threshold(ImageReduced_inner, &Region_inner, 0,m_Parameters.radius_ext2_thred , 1);//Mean_inner-30
	  union2(Region_ext, Region_inner, &RegionUnion);
	  connection(RegionUnion, &ConnectedRegions);
	  select_shape(ConnectedRegions, &SelectedRegions, "area", "and", m_Parameters.ARMin, 99999);
	  count_obj(SelectedRegions, &Number);
	  /////////////////////////////////////////////////*/
	  // Number_QiPao=1;
	  if ((Number<=0))
	  {
		  ;
		  //pData->m_isFail= false;
		  //testItem->m_bFailSubTest = false;
	  }
	  else
	  {
		  pData->m_isFail = true;
		  testItem->m_bFailSubTest = true;
		  //testItem->m_ErrorMsg = "Error No Find Center";
		  //testItem->m_ErrorY = 250;
		  //testItem->m_ErrorX = 350;
		  //testItem->m_ErrorR = 55;
		  set_color(pData->m_ShowHWindow,"red");
		  disp_region(SelectedRegions,pData->m_ShowHWindow);
		  //disp_circle(pData->m_ShowHWindow,Row,Column,85);
	  }
  }
  catch (HException &except) 
  {
	  pData->m_isFail = true;
	  testItem->m_bFailSubTest = true;
	  //testItem->m_ErrorMsg = except.file;
	  //testItem->m_ErrorMsg += " ";
	  //testItem->m_ErrorMsg += except.line;
	  //testItem->m_ErrorMsg += " ";
	  //testItem->m_ErrorMsg += except.message;
	  testItem->m_ErrorY = 1;
	  testItem->m_ErrorX = 1;
	  testItem->m_ErrorR = 4;
  }
}
Exemple #10
0
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///// edit traps
int editmap::edit_trp(point coords)
{
    int ret = 0;
    int pwh = TERRAIN_WINDOW_HEIGHT - infoHeight - 1;

    WINDOW *w_picktrap = newwin(pwh, width, VIEW_OFFSET_Y, TERRAIN_WINDOW_WIDTH + VIEW_OFFSET_X);
    wborder(w_picktrap, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
            LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );
    int tmax = pwh - 4;
    int tshift = 0;
    int subch = 0;
    if ( trsel == -1 ) {
        trsel = cur_trap;
    }
    std::string trids[num_trap_types];
    trids[0] = _("-clear-");
    do {
        uphelp("[s/tab] shape select, [m]ove, [v] showall",
               "[enter] change, [t] change/quit, [q]uit", "Traps");

        if( trsel < tshift ) {
            tshift = trsel;
        } else if ( trsel > tshift + tmax ) {
            tshift = trsel - tmax;
        }
        std::string tnam;
        for ( int t = tshift; t <= tshift + tmax; t++ ) {
            mvwprintz(w_picktrap, t + 1 - tshift, 1, c_white, "%s", padding.c_str());
            if ( t < num_trap_types ) {
                tnam = ( g->traps[t]->name.size() == 0 ? trids[t] : g->traps[t]->name );
                mvwputch(w_picktrap, t + 1 - tshift, 2, g->traps[t]->color, g->traps[t]->sym);
                mvwprintz(w_picktrap, t + 1 - tshift, 4, (trsel == t ? h_white : ( cur_trap == t ? c_green : c_ltgray ) ), "%d %s", t, tnam.c_str() );
            }
        }
        wrefresh(w_picktrap);

        subch = (int)getch();
        if(subch == KEY_UP) {
            trsel--;
        } else if (subch == KEY_DOWN) {
            trsel++;
        } else if ( subch == KEY_ENTER || subch == '\n' || subch == 't' ) {
            if ( trsel < num_trap_types && trsel >= 0 ) {
                trset = trsel;
            }
            for(int t = 0; t < target_list.size(); t++ ) {
                g->m.add_trap(target_list[t].x, target_list[t].y, trap_id(trset));
            }
            if ( subch == 't' ) {
                subch = KEY_ESCAPE;
            }
            update_view(false);
        } else if ( subch == 's' || subch == '\t' || subch == 'm' ) {
            int sel_tmp = trsel;
            select_shape(editshape, ( subch == 'm' ? 1 : 0 ) );
            sel_frn = sel_tmp;
        } else if ( subch == 'v' ) {
            uberdraw = !uberdraw;
            update_view(false);
        }

        if( trsel < 0 ) {
            trsel = num_trap_types - 1;
        } else if ( trsel >= num_trap_types ) {
            trsel = 0;
        }

    } while ( ! menu_escape ( subch ) );
    werase(w_picktrap);
    wrefresh(w_picktrap);
    delwin(w_picktrap);

    wrefresh(w_info);

    return ret;
}
Exemple #11
0
int editmap::edit_fld(point coords)
{
    int ret = 0;
    uimenu fmenu;
    fmenu.w_width = width;
    fmenu.w_height = TERRAIN_WINDOW_HEIGHT - infoHeight;
    fmenu.w_y = 0;
    fmenu.w_x = TERRAIN_WINDOW_WIDTH + VIEW_OFFSET_X;
    fmenu.return_invalid = true;
    setup_fmenu(&fmenu, cur_field);

    do {
        uphelp("[s/tab] shape select, [m]ove, [<,>] density",
               "[enter] edit, [q]uit, [v] showall", "Field effects");

        fmenu.query(false);
        if ( fmenu.selected > 0 && fmenu.selected < num_fields &&
             ( fmenu.keypress == '\n' || fmenu.keypress == KEY_LEFT || fmenu.keypress == KEY_RIGHT )
           ) {
            int fdens = 0;
            int idx = fmenu.selected;
            field_entry *fld = cur_field->findField((field_id)idx);
            if ( fld != NULL ) {
                fdens = fld->getFieldDensity();
            }
            int fsel_dens = fdens;
            if ( fmenu.keypress == '\n' ) {
                uimenu femenu;
                femenu.w_width = width;
                femenu.w_height = infoHeight;
                femenu.w_y = fmenu.w_height;
                femenu.w_x = TERRAIN_WINDOW_WIDTH + VIEW_OFFSET_X;

                femenu.return_invalid = true;
                field_t ftype = fieldlist[idx];
                int fidens = ( fdens == 0 ? 0 : fdens - 1 );
                femenu.text = ( ftype.name[fidens].size() == 0 ? fids[idx] : ftype.name[fidens] );
                femenu.addentry("-clear-");

                femenu.addentry("1: %s", ( ftype.name[0].size() == 0 ? fids[idx].c_str() : ftype.name[0].c_str() ));
                femenu.addentry("2: %s", ( ftype.name[1].size() == 0 ? fids[idx].c_str() : ftype.name[1].c_str() ));
                femenu.addentry("3: %s", ( ftype.name[2].size() == 0 ? fids[idx].c_str() : ftype.name[2].c_str() ));
                femenu.entries[fdens].text_color = c_cyan;
                femenu.selected = ( sel_fdensity > 0 ? sel_fdensity : fdens );

                femenu.query();
                if ( femenu.ret >= 0 ) {
                    fsel_dens = femenu.ret;
                }
            } else if ( fmenu.keypress == KEY_RIGHT && fdens < 3 ) {
                fsel_dens++;
            } else if ( fmenu.keypress == KEY_LEFT && fdens > 0 ) {
                fsel_dens--;
            }
            if ( fdens != fsel_dens || target_list.size() > 1 ) {
                for(int t = 0; t < target_list.size(); t++ ) {
                    field *t_field = &g->m.field_at(target_list[t].x, target_list[t].y);
                    field_entry *t_fld = t_field->findField((field_id)idx);
                    int t_dens = 0;
                    if ( t_fld != NULL ) {
                        t_dens = t_fld->getFieldDensity();
                    }
                    if ( fsel_dens != 0 ) {
                        if ( t_dens != 0 ) {
                            t_fld->setFieldDensity(fsel_dens);
                        } else {
                            g->m.add_field(g, target_list[t].x, target_list[t].y, (field_id)idx, fsel_dens );
                        }
                    } else {
                        if ( t_dens != 0 ) {
                            t_field->removeField( (field_id)idx );
                        }
                    }
                }
                update_fmenu_entry( &fmenu, cur_field, idx );
                update_view(true);
                sel_field = fmenu.selected;
                sel_fdensity = fsel_dens;
            }
        } else if ( fmenu.selected == 0 && fmenu.keypress == '\n' ) {
            for(int t = 0; t < target_list.size(); t++ ) {
                field *t_field = &g->m.field_at(target_list[t].x, target_list[t].y);
                if ( t_field->fieldCount() > 0 ) {
                    for ( std::map<field_id, field_entry *>::iterator field_list_it = t_field->getFieldStart();
                          field_list_it != t_field->getFieldEnd(); ++field_list_it
                        ) {
                        field_id rmid = field_list_it->first;
                        t_field->removeField( rmid );
                        if ( target_list[t].x == target.x && target_list[t].y == target.y ) {
                            update_fmenu_entry( &fmenu, t_field, (int)rmid );
                        }
                    }
                }
            }
            update_view(true);
            sel_field = fmenu.selected;
            sel_fdensity = 0;
        } else if ( fmenu.keypress == 's' || fmenu.keypress == '\t' || fmenu.keypress == 'm' ) {
            int sel_tmp = fmenu.selected;
            int ret = select_shape(editshape, ( fmenu.keypress == 'm' ? 1 : 0 ) );
            if ( ret > 0 ) {
                setup_fmenu(&fmenu, cur_field);
            }
            fmenu.selected = sel_tmp;
        } else if ( fmenu.keypress == 'v' ) {
            uberdraw = !uberdraw;
            update_view(false);
        }
    } while ( ! menu_escape ( fmenu.keypress ) );
    wrefresh(w_info);
    return ret;
}
Exemple #12
0
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///// edit terrain type / furniture
int editmap::edit_ter(point coords)
{
    int ret = 0;
    int pwh = TERRAIN_WINDOW_HEIGHT - 4;

    WINDOW *w_pickter = newwin(pwh, width, VIEW_OFFSET_Y, TERRAIN_WINDOW_WIDTH + VIEW_OFFSET_X);
    wborder(w_pickter, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
            LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );
    wrefresh(w_pickter);

    int pickh = pwh - 2;
    int pickw = width - 4;

    if( sel_ter < 0 ) {
        sel_ter = target_ter;
    }

    if( sel_frn < 0 ) {
        sel_frn = target_frn;
    }

    int lastsel_ter = sel_ter;
    int lastsel_frn = sel_frn;

    int xmax = pickw;
    int tymax = int(num_terrain_types / xmax);
    if ( tymax % xmax != 0 ) {
        tymax++;
    }
    int fymax = int(num_furniture_types / xmax);
    if ( fymax == 0 || fymax % xmax != 0 ) {
        fymax++;
    }

    int subch = 0;
    point sel_terp = point(-1, -1);     // screen coords of current selection
    point lastsel_terp = point(-1, -1); // and last selection
    point target_terp = point(-1, -1);  // and current tile
    point sel_frnp = point(-1, -1);     // for furniture ""
    point lastsel_frnp = point(-1, -1);
    point target_frnp = point(-1, -1);


    int mode = ter_frn_mode;
    do {
        if ( mode != ter_frn_mode ) {
            mode = ter_frn_mode;
            wrefresh(w_pickter);
        }

        // cursor is green for terrain or furniture, depending on selection
        nc_color c_tercurs = ( ter_frn_mode == 0 ? c_ltgreen : c_dkgray );
        nc_color c_frncurs = ( ter_frn_mode == 1 ? c_ltgreen : c_dkgray );

        int cur_t = 0;
        int tstart = 2;
        // draw icon grid
        for (int y = tstart; y < pickh && cur_t < num_terrain_types; y += 2) {
            for (int x = 3; x < pickw && cur_t < num_terrain_types; x++, cur_t++) {
                ter_t ttype = terlist[cur_t];
                mvwputch(w_pickter, y, x, ( ter_frn_mode == 0 ? ttype.color : c_dkgray ) , ttype.sym);
                if(cur_t == sel_ter) {
                    sel_terp = point(x, y);
                } else if(cur_t == lastsel_ter) {
                    lastsel_terp = point(x, y);
                } else if (cur_t == target_ter) {
                    target_terp = point(x, y);
                }
            }
        }
        // clear last cursor area
        mvwputch(w_pickter, lastsel_terp.y + 1, lastsel_terp.x - 1, c_tercurs, ' ');
        mvwputch(w_pickter, lastsel_terp.y - 1, lastsel_terp.x + 1, c_tercurs, ' ');
        mvwputch(w_pickter, lastsel_terp.y + 1, lastsel_terp.x + 1, c_tercurs, ' ');
        mvwputch(w_pickter, lastsel_terp.y - 1, lastsel_terp.x - 1, c_tercurs, ' ');
        // indicate current tile
        mvwputch(w_pickter, target_terp.y + 1, target_terp.x, c_ltgray, '^');
        mvwputch(w_pickter, target_terp.y - 1, target_terp.x, c_ltgray, 'v');
        // draw cursor around selected terrain icon
        mvwputch(w_pickter, sel_terp.y + 1, sel_terp.x - 1, c_tercurs, LINE_XXOO);
        mvwputch(w_pickter, sel_terp.y - 1, sel_terp.x + 1, c_tercurs, LINE_OOXX);
        mvwputch(w_pickter, sel_terp.y + 1, sel_terp.x + 1, c_tercurs, LINE_XOOX);
        mvwputch(w_pickter, sel_terp.y - 1, sel_terp.x - 1, c_tercurs, LINE_OXXO);

        wborder(w_pickter, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
                LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );
        // calc offset, print terrain selection info
        int tlen = tymax * 2;
        int off = tstart + tlen;
        mvwprintw(w_pickter, off, 1, "%s", padding.c_str());
        if( ter_frn_mode == 0 ) { // unless furniture is selected
            ter_t pttype = terlist[sel_ter];

            mvwprintw(w_pickter, 0, 2, "< %d: %s >-----------", sel_ter, pttype.name.c_str());
            mvwprintz(w_pickter, off, 2, c_white, _("movecost %d"), pttype.movecost);
            std::string extras = "";
            if(pttype.flags & mfb(indoors)) {
                extras += _("[indoors] ");
            }
            if(pttype.flags & mfb(supports_roof)) {
                extras += _("[roof] ");
            }
            wprintw(w_pickter, " %s", extras.c_str());
        }

        off += 2;
        int cur_f = 0;
        int fstart = off; // calc vertical offset, draw furniture icons
        for (int y = fstart; y < pickh && cur_f < num_furniture_types; y += 2) {
            for (int x = 3; x < pickw && cur_f < num_furniture_types; x++, cur_f++) {

                furn_t ftype = furnlist[cur_f];
                mvwputch(w_pickter, y, x, ( ter_frn_mode == 1 ? ftype.color : c_dkgray ), ftype.sym);

                if(cur_f == sel_frn) {
                    sel_frnp = point(x, y);
                } else if(cur_f == lastsel_frn) {
                    lastsel_frnp = point(x, y);
                } else if (cur_f == target_frn) {
                    target_frnp = point(x, y);
                }
            }
        }

        mvwputch(w_pickter, lastsel_frnp.y + 1, lastsel_frnp.x - 1, c_frncurs, ' ');
        mvwputch(w_pickter, lastsel_frnp.y - 1, lastsel_frnp.x + 1, c_frncurs, ' ');
        mvwputch(w_pickter, lastsel_frnp.y + 1, lastsel_frnp.x + 1, c_frncurs, ' ');
        mvwputch(w_pickter, lastsel_frnp.y - 1, lastsel_frnp.x - 1, c_frncurs, ' ');

        mvwputch(w_pickter, target_frnp.y + 1, target_frnp.x, c_ltgray, '^');
        mvwputch(w_pickter, target_frnp.y - 1, target_frnp.x, c_ltgray, 'v');

        mvwputch(w_pickter, sel_frnp.y + 1, sel_frnp.x - 1, c_frncurs, LINE_XXOO);
        mvwputch(w_pickter, sel_frnp.y - 1, sel_frnp.x + 1, c_frncurs, LINE_OOXX);
        mvwputch(w_pickter, sel_frnp.y + 1, sel_frnp.x + 1, c_frncurs, LINE_XOOX);
        mvwputch(w_pickter, sel_frnp.y - 1, sel_frnp.x - 1, c_frncurs, LINE_OXXO);

        int flen = fymax * 2;
        off += flen;
        mvwprintw(w_pickter, off, 1, "%s", padding.c_str());
        if( ter_frn_mode == 1 ) {

            furn_t pftype = furnlist[sel_frn];

            mvwprintw(w_pickter, 0, 2, "< %d: %s >-----------", sel_frn, pftype.name.c_str());
            mvwprintz(w_pickter, off, 2, c_white, _("movecost %d"), pftype.movecost);
            std::string fextras = "";
            if(pftype.flags & mfb(indoors)) {
                fextras += _("[indoors] ");
            }
            if(pftype.flags & mfb(supports_roof)) {
                fextras += _("[roof] ");
            }
            wprintw(w_pickter, " %s", fextras.c_str());
        }

        // draw green |'s around terrain or furniture tilesets depending on selection
        for (int y = tstart - 1; y < tstart + tlen + 1; y++ ) {
            mvwputch(w_pickter, y, 1, c_ltgreen, ( ter_frn_mode == 0 ? '|' : ' ' ) );
            mvwputch(w_pickter, y, width - 2, c_ltgreen, ( ter_frn_mode == 0 ? '|' : ' ' ) );
        }
        for (int y = fstart - 1; y < fstart + flen + 1; y++ ) {
            mvwputch(w_pickter, y, 1, c_ltgreen, ( ter_frn_mode == 1 ? '|' : ' ' ) );
            mvwputch(w_pickter, y, width - 2, c_ltgreen, ( ter_frn_mode == 1 ? '|' : ' ' ) );
        }

        uphelp("[s/tab] shape select, [m]ove, [<>^v] select",
               "[enter] change, [g] change/quit, [q]uit, [v] showall",
               "Terrain / Furniture");

        wrefresh(w_pickter);

        subch = (int)getch();
        lastsel_ter = sel_ter;
        lastsel_frn = sel_frn;
        if ( ter_frn_mode == 0 ) {
            if( subch == KEY_LEFT ) {
                sel_ter = (sel_ter - 1 >= 0 ? sel_ter - 1 : num_terrain_types - 1);
            } else if( subch == KEY_RIGHT ) {
                sel_ter = (sel_ter + 1 < num_terrain_types ? sel_ter + 1 : 0 );
            } else if( subch == KEY_UP ) {
                if (sel_ter - xmax + 3 > 0 ) {
                    sel_ter = sel_ter - xmax + 3;
                } else {
                    ter_frn_mode = ( ter_frn_mode == 0 ? 1 : 0 );
                }
            } else if( subch == KEY_DOWN ) {
                if (sel_ter + xmax - 3 < num_terrain_types ) {
                    sel_ter = sel_ter + xmax - 3;
                } else {
                    ter_frn_mode = ( ter_frn_mode == 0 ? 1 : 0 );
                }
            } else if( subch == KEY_ENTER || subch == '\n' || subch == 'g' ) {
                for(int t = 0; t < target_list.size(); t++ ) {
                    g->m.ter_set(target_list[t].x, target_list[t].y, (ter_id)sel_ter);
                }
                if ( subch == 'g' ) {
                    subch = KEY_ESCAPE;
                }
                update_view(false);
            } else if ( subch == 's'  || subch == '\t' || subch == 'm'  ) {
                int sel_tmp = sel_ter;
                select_shape(editshape, ( subch == 'm' ? 1 : 0 ) );
                sel_ter = sel_tmp;
            } else if ( subch == 'v' ) {
                uberdraw = !uberdraw;
                update_view(false);
            }
        } else { // todo: cleanup
            if( subch == KEY_LEFT ) {
                sel_frn = (sel_frn - 1 >= 0 ? sel_frn - 1 : num_furniture_types - 1);
            } else if( subch == KEY_RIGHT ) {
                sel_frn = (sel_frn + 1 < num_furniture_types ? sel_frn + 1 : 0 );
            } else if( subch == KEY_UP ) {
                if ( sel_frn - xmax + 3 > 0 ) {
                    sel_frn = sel_frn - xmax + 3;
                } else {
                    ter_frn_mode = ( ter_frn_mode == 0 ? 1 : 0 );
                }
            } else if( subch == KEY_DOWN ) {
                if ( sel_frn + xmax - 3 < num_furniture_types ) {
                    sel_frn = sel_frn + xmax - 3;
                } else {
                    ter_frn_mode = ( ter_frn_mode == 0 ? 1 : 0 );
                }
            } else if( subch == KEY_ENTER || subch == '\n' || subch == 'g' ) {
                for(int t = 0; t < target_list.size(); t++ ) {
                    g->m.furn_set(target_list[t].x, target_list[t].y, (furn_id)sel_frn);
                }
                if ( subch == 'g' ) {
                    subch = KEY_ESCAPE;
                }
                update_view(false);
            } else if ( subch == 's' || subch == '\t' || subch == 'm' ) {
                int sel_frn_tmp = sel_frn;
                int sel_ter_tmp = sel_ter;
                select_shape(editshape, ( subch == 'm' ? 1 : 0 ) );
                sel_frn = sel_frn_tmp;
                sel_ter = sel_ter_tmp;
            } else if ( subch == 'v' ) {
                uberdraw = !uberdraw;
                update_view(false);
            }
        }
    } while ( ! menu_escape ( subch ) );

    werase(w_pickter);
    wrefresh(w_pickter);

    delwin(w_pickter);
    return ret;
}