/// <summary> /// Infer the new shape based on the resize policy. /// </summary> /// <param name="p">Specifies the ResizeParameter with the resize policy.</param> /// <param name="nOldWidth">Specifies the old width.</param> /// <param name="nOldHeight">Specifies the old height.</param> /// <param name="nNewWidth">Specifies the new 'inferred' width.</param> /// <param name="nNewHeight">Specifies the new 'inferred' width.</param> public void InferNewSize(ResizeParameter p, int nOldWidth, int nOldHeight, out int nNewWidth, out int nNewHeight) { int height = (int)p.height; int width = (int)p.width; float fOrigAspect = (float)nOldWidth / (float)nOldHeight; float fAspect = (float)width / (float)height; switch (p.resize_mode) { case ResizeParameter.ResizeMode.WARP: break; case ResizeParameter.ResizeMode.FIT_LARGE_SIZE_AND_PAD: break; case ResizeParameter.ResizeMode.FIT_SMALL_SIZE: if (fOrigAspect < fAspect) { height = (int)(width / fOrigAspect); } else { width = (int)(fOrigAspect * height); } break; default: m_log.FAIL("Unknown resize mode '" + p.resize_mode.ToString() + "'!"); break; } nNewHeight = height; nNewWidth = width; }
/** @copydoc LayerParameterBase::Copy */ public override void Copy(LayerParameterBase src) { TransformationParameter p = (TransformationParameter)src; m_bUseImageDbMean = p.m_bUseImageDbMean; m_bForceColor = p.m_bForceColor; m_bForceGray = p.m_bForceGray; m_bMirror = p.m_bMirror; m_dfScale = p.m_dfScale; m_scaleOperator = p.m_scaleOperator; m_nCropSize = p.m_nCropSize; m_rgMeanValue = Utility.Clone <double>(p.m_rgMeanValue); m_dfForcedPositiveRangeMax = p.m_dfForcedPositiveRangeMax; m_nRandomSeed = p.m_nRandomSeed; m_strMeanFile = p.m_strMeanFile; m_colorOrder = p.m_colorOrder; m_resize = (p.resize_param == null) ? null : p.resize_param.Clone(); m_noise = (p.noise_param == null) ? null : p.noise_param.Clone(); m_distortion = (p.distortion_param == null) ? null : p.distortion_param.Clone(); m_expansion = (p.expansion_param == null) ? null : p.expansion_param.Clone(); m_emitConstraint = (p.emit_constraint == null) ? null : p.emit_constraint.Clone(); if (p.mask_param != null) { m_mask = p.mask_param.Clone(); } if (p.label_mapping != null) { m_labelMapping = p.label_mapping.Clone(); } }
/// <summary>获取图片的二进制数据 /// </summary> /// <param name="imagePath">图片保存路径</param> /// <param name="resizeParameter">图片尺寸调整参数</param> /// <param name="lastWriteTimeUtc">最后修改时间</param> /// <returns></returns> public async Task <byte[]> GetImageData(string imagePath, ResizeParameter resizeParameter, DateTime lastWriteTimeUtc) { try { var key = $"{imagePath}{resizeParameter.ToString()}{lastWriteTimeUtc.ToString("yyyy-MM-dd HH:mm:ss")}"; var cacheKey = $"Image:{ShaUtil.GetHex16StringSha1Hash(key)}"; byte[] imageBytes; if (_option.EnableImageCache) { var imageCacheItem = await _imageCache.GetAsync(cacheKey); if (imageCacheItem != null) { return(imageCacheItem.Data); } } //图片操作 var image = Image.FromFile(imagePath); //对图片进行相应的操作,放大等 Image resizeImage = null; if (resizeParameter.Mode == ResizeMode.Zoom) { resizeImage = ImageResize.ImageResizer.Zoom(image, resizeParameter); } else if (resizeParameter.Mode == ResizeMode.Crop) { //图片裁剪 resizeImage = ImageResize.ImageResizer.Crop(image, resizeParameter); } var imageFormat = ImageUtil.GetImageFormatByFormatName(resizeParameter.Format); imageBytes = ImageHelper.ImageCompressToBytes(resizeImage, resizeParameter.Quality, imageFormat); image.Dispose(); //只有开启图片缓存情况下,才会对图片再次进行缓存 if (_option.EnableImageCache) { //将图片缓存 await _imageCache.SetAsync(cacheKey, new ImageCacheItem(imageBytes), new DistributedCacheEntryOptions() { SlidingExpiration = TimeSpan.FromSeconds(_option.ImageCacheSlidingExpirationSeconds) }); } return(imageBytes); } catch (Exception ex) { _logger.LogError("Resize图片出现错误,{0}", ex.Message); } return(default);
/// <summary> /// Setup the layer. /// </summary> /// <param name="colBottom">Specifies the collection of bottom (input) Blobs.</param> /// <param name="colTop">Specifies the collection of top (output) Blobs.</param> public override void LayerSetUp(BlobCollection <T> colBottom, BlobCollection <T> colTop) { m_log.CHECK_GT(m_param.detection_evaluate_param.num_classes, 1, "There must be at least one class!"); m_nNumClasses = (int)m_param.detection_evaluate_param.num_classes; m_nBackgroundLabelId = (int)m_param.detection_evaluate_param.background_label_id; m_fOverlapThreshold = m_param.detection_evaluate_param.overlap_threshold; m_log.CHECK_GT(m_fOverlapThreshold, 0.0f, "The overlap_threshold must be non-negative."); m_bEvaluateDifficultGt = m_param.detection_evaluate_param.evaulte_difficult_gt; if (File.Exists(m_param.detection_evaluate_param.name_size_file)) { using (StreamReader sr = new StreamReader(m_param.detection_evaluate_param.name_size_file)) { string strLine = sr.ReadLine(); while (strLine != null) { string[] rgstr = strLine.Split(' ', ','); if (rgstr.Length == 3 || rgstr.Length == 4) { int nNameIdx = (rgstr.Length == 4) ? 1 : 0; string strName = rgstr[nNameIdx].Trim(','); int nHeight = int.Parse(rgstr[nNameIdx + 1].Trim(',')); int nWidth = int.Parse(rgstr[nNameIdx + 2].Trim(',')); m_rgSizes.Add(new SizeF(nWidth, nHeight)); } strLine = sr.ReadLine(); } } } m_nCount = 0; // If there is no name_size_provided, use normalized bbox to evaluate. m_bUseNormalizedBbox = (m_rgSizes.Count == 0) ? true : false; // Retrieve resize parameter if there is one provided. m_resizeParam = m_param.detection_evaluate_param.resize_param; }
/// <summary> /// The ApplyResize method resizes the SimpleDatum containing an image to a newly resized image as specified by the resize parameter. /// </summary> /// <param name="sd">Specifies the SimpleDatum to resize - must contain a 3 channel image.</param> /// <param name="p">Specifies the resize parameter to apply.</param> /// <returns>The newly resized SimpleDatum is returned.</returns> public SimpleDatum ApplyResize(SimpleDatum sd, ResizeParameter p) { if (p.width == sd.Width && p.height == sd.Height) { return(sd); } Bitmap bmp = ImageData.GetImage(sd); Bitmap bmpNew = ImageTools.ResizeImage(bmp, (int)p.width, (int)p.height); SimpleDatum sdResize = ImageData.GetImageData(bmpNew, sd, false); SimpleDatum sdNew = new SimpleDatum(sd); sdNew.CopyData(sdResize); bmp.Dispose(); bmpNew.Dispose(); return(sdNew); }
/// <summary>获取请求参数 /// </summary> private ResizeParameter GetResizeParameter(IQueryCollection query) { ResizeParameter resizeParameter = new ResizeParameter { //Format Format = GetQueryValue(query, "format", ImageUtil.DefaultFormatName), //自动旋转 AutoRotate = bool.Parse(GetQueryValue(query, "autorotate", "false")), //质量 Quality = int.Parse(GetQueryValue(query, "q", "100")), //宽度 Width = int.Parse(GetQueryValue(query, "w", "0")), //高度 Height = int.Parse(GetQueryValue(query, "h", "0")), //模式 Mode = GetQueryValue(query, "mode", ResizeMode.Zoom), //x CropX = int.Parse(GetQueryValue(query, "x", "0")), //y CropY = int.Parse(GetQueryValue(query, "y", "0")) }; return(resizeParameter); }
/// <summary> /// Update the BBox size based on the Resize policy. /// </summary> /// <param name="p">Specifies the ResizeParameter with the resize policy.</param> /// <param name="nOldWidth">Specifies the old width.</param> /// <param name="nOldHeight">Specifies the old height.</param> /// <param name="bbox1">Specifies the BBox to update.</param> /// <returns>The update NormalizedBBox is returned.</returns> public NormalizedBBox UpdateBBoxByResizePolicy(ResizeParameter p, int nOldWidth, int nOldHeight, NormalizedBBox bbox1) { NormalizedBBox bbox = bbox1.Clone(); float fNewHeight = p.height; float fNewWidth = p.width; float fOrigAspect = (float)nOldWidth / (float)nOldHeight; float fNewAspect = fNewWidth / fNewHeight; float fxmin = bbox.xmin * nOldWidth; float fymin = bbox.ymin * nOldHeight; float fxmax = bbox.xmax * nOldWidth; float fymax = bbox.ymax * nOldHeight; float fPadding; switch (p.resize_mode) { case ResizeParameter.ResizeMode.WARP: fxmin = (float)Math.Max(0.0, fxmin * fNewWidth / nOldWidth); fxmax = (float)Math.Min(fNewWidth, fxmax * fNewWidth / nOldWidth); fymin = (float)Math.Max(0.0, fymin * fNewHeight / nOldHeight); fymax = (float)Math.Min(fNewHeight, fymax * fNewHeight / nOldHeight); break; case ResizeParameter.ResizeMode.FIT_LARGE_SIZE_AND_PAD: if (fOrigAspect > fNewAspect) { fPadding = (fNewHeight - fNewWidth / fOrigAspect) / 2; fxmin = (float)Math.Max(0.0, fxmin * fNewWidth / nOldWidth); fxmax = (float)Math.Min(fNewWidth, fxmax * fNewWidth / nOldWidth); fymin = fymin * (fNewHeight - 2 * fPadding) / nOldHeight; fymin = fPadding + Math.Max(0, fymin); fymax = fymax * (fNewHeight - 2 * fPadding) / nOldHeight; fymax = fPadding + Math.Min(fNewHeight, fymax); } else { fPadding = (fNewWidth - fOrigAspect * fNewHeight) / 2; fxmin = fxmin * (fNewWidth - 2 * fPadding) / nOldWidth; fxmin = fPadding + Math.Max(0, fxmin); fxmax = fxmax * (fNewWidth - 2 * fPadding) / nOldWidth; fxmax = fPadding + Math.Min(fNewWidth, fxmax); fymin = (float)Math.Max(0.0, fymin * fNewHeight / nOldHeight); fymax = (float)Math.Min(fNewHeight, fymax * fNewHeight / nOldHeight); } break; case ResizeParameter.ResizeMode.FIT_SMALL_SIZE: if (fOrigAspect < fNewAspect) { fNewHeight = fNewWidth / fOrigAspect; } else { fNewWidth = fOrigAspect * fNewHeight; } fxmin = (float)Math.Max(0.0, fxmin * fNewWidth / nOldWidth); fxmax = (float)Math.Min(fNewWidth, fxmax * fNewWidth / nOldWidth); fymin = (float)Math.Max(0.0, fymin * fNewHeight / nOldHeight); fymax = (float)Math.Min(fNewHeight, fymax * fNewHeight / nOldHeight); break; default: m_log.FAIL("Unknown resize mode '" + p.resize_mode.ToString() + "'!"); break; } bbox.xmin = fxmin / fNewWidth; bbox.ymin = fymin / fNewHeight; bbox.xmax = fxmax / fNewWidth; bbox.ymax = fymax / fNewHeight; return(bbox); }
/// <summary> /// Parses the parameter from a RawProto. /// </summary> /// <param name="rp">Specifies the RawProto to parse.</param> /// <returns>A new instance of the parameter is returned.</returns> public static TransformationParameter FromProto(RawProto rp) { string strVal; TransformationParameter p = new TransformationParameter(); if ((strVal = rp.FindValue("scale")) != null) { p.scale = ParseDouble(strVal); } if ((strVal = rp.FindValue("scale_operator")) != null) { if (strVal == SCALE_OPERATOR.MUL.ToString()) { p.scale_operator = SCALE_OPERATOR.MUL; } else if (strVal == SCALE_OPERATOR.POW.ToString()) { p.scale_operator = SCALE_OPERATOR.POW; } else { p.scale_operator = SCALE_OPERATOR.NONE; } } else { p.scale_operator = null; } if ((strVal = rp.FindValue("mirror")) != null) { p.mirror = bool.Parse(strVal); } if ((strVal = rp.FindValue("crop_size")) != null) { p.crop_size = uint.Parse(strVal); } if ((strVal = rp.FindValue("use_image_mean")) != null || (strVal = rp.FindValue("use_imagedb_mean")) != null) { p.use_imagedb_mean = bool.Parse(strVal); } if ((strVal = rp.FindValue("mean_file")) != null) { p.use_imagedb_mean = true; } p.mean_value = rp.FindArray <double>("mean_value"); if ((strVal = rp.FindValue("force_color")) != null) { p.force_color = bool.Parse(strVal); } if ((strVal = rp.FindValue("force_gray")) != null) { p.force_gray = bool.Parse(strVal); } if ((strVal = rp.FindValue("force_positive_range_max")) != null) { p.forced_positive_range_max = ParseDouble(strVal); } if ((strVal = rp.FindValue("mean_file")) != null) { p.mean_file = strVal; } if ((strVal = rp.FindValue("color_order")) != null) { if (strVal == COLOR_ORDER.BGR.ToString()) { p.color_order = COLOR_ORDER.BGR; } else { p.color_order = COLOR_ORDER.RGB; } } RawProto rpResize = rp.FindChild("resize_param"); if (rpResize != null) { p.resize_param = ResizeParameter.FromProto(rpResize); } else { p.resize_param = null; } RawProto rpNoise = rp.FindChild("noise_param"); if (rpNoise != null) { p.noise_param = NoiseParameter.FromProto(rpNoise); } else { p.noise_param = null; } RawProto rpDistort = rp.FindChild("distortion_param"); if (rpDistort != null) { p.distortion_param = DistortionParameter.FromProto(rpDistort); } RawProto rpExpand = rp.FindChild("expansion_param"); if (rpExpand != null) { p.expansion_param = ExpansionParameter.FromProto(rpExpand); } else { p.expansion_param = null; } RawProto rpEmitCon = rp.FindChild("emit_constraint"); if (rpEmitCon != null) { p.emit_constraint = EmitConstraint.FromProto(rpEmitCon); } else { p.emit_constraint = null; } RawProto rpMask = rp.FindChild("mask_param"); if (rpMask != null) { p.mask_param = MaskParameter.FromProto(rpMask); } RawProto rpLabelMapping = rp.FindChild("label_mapping"); if (rpLabelMapping != null) { p.label_mapping = DataLabelMappingParameter.FromProto(rpLabelMapping); } return(p); }
/// <summary> /// Setup the layer. /// </summary> /// <param name="colBottom">Specifies the collection of bottom (input) Blobs.</param> /// <param name="colTop">Specifies the collection of top (output) Blobs.</param> public override void LayerSetUp(BlobCollection <T> colBottom, BlobCollection <T> colTop) { m_log.CHECK_GT(m_param.detection_output_param.num_classes, 0, "There must be at least one class specified."); m_nNumClasses = (int)m_param.detection_output_param.num_classes; m_bShareLocations = m_param.detection_output_param.share_location; m_nNumLocClasses = (m_bShareLocations) ? 1 : m_nNumClasses; m_nBackgroundLabelId = m_param.detection_output_param.background_label_id; m_codeType = m_param.detection_output_param.code_type; m_bVarianceEncodedInTarget = m_param.detection_output_param.variance_encoded_in_target; m_nKeepTopK = m_param.detection_output_param.keep_top_k; m_fConfidenceThreshold = m_param.detection_output_param.confidence_threshold.GetValueOrDefault(-float.MaxValue); // Parameters used in nms. m_fNmsThreshold = m_param.detection_output_param.nms_param.nms_threshold; m_log.CHECK_GE(m_fNmsThreshold, 0, "The nms_threshold must be non negative."); m_fEta = m_param.detection_output_param.nms_param.eta; m_log.CHECK_GT(m_fEta, 0, "The nms_param.eta must be > 0."); m_log.CHECK_LE(m_fEta, 1, "The nms_param.eta must be < 0."); m_nTopK = m_param.detection_output_param.nms_param.top_k.GetValueOrDefault(-1); m_strOutputDir = m_param.detection_output_param.save_output_param.output_directory; m_bNeedSave = !string.IsNullOrEmpty(m_strOutputDir); if (m_bNeedSave && !Directory.Exists(m_strOutputDir)) { Directory.CreateDirectory(m_strOutputDir); } m_strOutputNamePrefix = m_param.detection_output_param.save_output_param.output_name_prefix; m_outputFormat = m_param.detection_output_param.save_output_param.output_format; if (!string.IsNullOrEmpty(m_param.detection_output_param.save_output_param.label_map_file)) { string strLabelMapFile = m_param.detection_output_param.save_output_param.label_map_file; if (!File.Exists(strLabelMapFile)) { // Ignore saving if there is no label map file. m_log.WriteLine("WARNING: Could not find the label_map_file '" + strLabelMapFile + "'!"); m_bNeedSave = false; } else { LabelMap label_map; try { RawProto proto = RawProto.FromFile(strLabelMapFile); label_map = LabelMap.FromProto(proto); } catch (Exception excpt) { throw new Exception("Failed to read label map file!", excpt); } try { m_rgLabelToName = label_map.MapToName(m_log, true, false); } catch (Exception excpt) { throw new Exception("Failed to convert the label to name!", excpt); } try { m_rgLabelToDisplayName = label_map.MapToName(m_log, true, true); } catch (Exception excpt) { throw new Exception("Failed to convert the label to display name!", excpt); } } } else { m_bNeedSave = false; } if (!string.IsNullOrEmpty(m_param.detection_output_param.save_output_param.name_size_file)) { string strNameSizeFile = m_param.detection_output_param.save_output_param.name_size_file; if (!File.Exists(strNameSizeFile)) { // Ignore saving if there is no name size file. m_log.WriteLine("WARNING: Could not find the name_size_file '" + strNameSizeFile + "'!"); m_bNeedSave = false; } else { using (StreamReader sr = new StreamReader(strNameSizeFile)) { string strName; int nHeight; int nWidth; string strLine = sr.ReadLine(); while (strLine != null) { string[] rgstr = strLine.Split(' '); if (rgstr.Length != 3 && rgstr.Length != 4) { throw new Exception("Invalid name_size_file format, expected 'name' 'height' 'width'"); } int nNameIdx = (rgstr.Length == 4) ? 1 : 0; strName = rgstr[nNameIdx].Trim(','); nHeight = int.Parse(rgstr[nNameIdx + 1].Trim(',')); nWidth = int.Parse(rgstr[nNameIdx + 2].Trim(',')); m_rgstrNames.Add(strName); m_rgSizes.Add(new SizeF(nWidth, nHeight)); strLine = sr.ReadLine(); } } if (m_param.detection_output_param.save_output_param.num_test_image.HasValue) { m_nNumTestImage = (int)m_param.detection_output_param.save_output_param.num_test_image.Value; } else { m_nNumTestImage = m_rgstrNames.Count; } m_log.CHECK_LE(m_nNumTestImage, m_rgstrNames.Count, "The number of test images cannot exceed the number of names."); } } else { m_bNeedSave = false; } if (m_param.detection_output_param.save_output_param.resize_param != null && m_param.detection_output_param.save_output_param.resize_param.Active) { m_resizeParam = m_param.detection_output_param.save_output_param.resize_param; } m_nNameCount = 0; m_bVisualize = m_param.detection_output_param.visualize; if (m_bVisualize) { m_fVisualizeThreshold = m_param.detection_output_param.visualize_threshold.GetValueOrDefault(0.6f); m_transformer = new DataTransformer <T>(m_cuda, m_log, m_param.transform_param, m_phase, 0, 0, 0); m_transformer.InitRand(); m_strSaveFile = m_param.detection_output_param.save_file; } m_blobBboxPreds.ReshapeLike(colBottom[0]); if (!m_bShareLocations) { m_blobBboxPermute.ReshapeLike(colBottom[0]); } m_blobConfPermute.ReshapeLike(colBottom[1]); }
/// <summary> /// Parses the parameter from a RawProto. /// </summary> /// <param name="rp">Specifies the RawProto to parse.</param> /// <returns>A new instance of the parameter is returned.</returns> public static TransformationParameter FromProto(RawProto rp) { string strVal; TransformationParameter p = new TransformationParameter(); if ((strVal = rp.FindValue("scale")) != null) { p.scale = double.Parse(strVal); } if ((strVal = rp.FindValue("mirror")) != null) { p.mirror = bool.Parse(strVal); } if ((strVal = rp.FindValue("crop_size")) != null) { p.crop_size = uint.Parse(strVal); } if ((strVal = rp.FindValue("use_image_mean")) != null || (strVal = rp.FindValue("use_imagedb_mean")) != null) { p.use_imagedb_mean = bool.Parse(strVal); } if ((strVal = rp.FindValue("mean_file")) != null) { p.use_imagedb_mean = true; } p.mean_value = rp.FindArray <double>("mean_value"); if ((strVal = rp.FindValue("force_color")) != null) { p.force_color = bool.Parse(strVal); } if ((strVal = rp.FindValue("force_gray")) != null) { p.force_gray = bool.Parse(strVal); } if ((strVal = rp.FindValue("force_positive_range_max")) != null) { p.forced_positive_range_max = double.Parse(strVal); } if ((strVal = rp.FindValue("mean_file")) != null) { p.mean_file = strVal; } if ((strVal = rp.FindValue("color_order")) != null) { if (strVal == COLOR_ORDER.BGR.ToString()) { p.color_order = COLOR_ORDER.BGR; } else { p.color_order = COLOR_ORDER.RGB; } } RawProto rpResize = rp.FindChild("resize_param"); p.resize_param = (rpResize != null) ? ResizeParameter.FromProto(rpResize) : null; RawProto rpNoise = rp.FindChild("noise_param"); p.noise_param = (rpNoise != null) ? NoiseParameter.FromProto(rpNoise) : null; RawProto rpDistort = rp.FindChild("distortion_param"); p.distortion_param = (rpDistort != null) ? DistortionParameter.FromProto(rpDistort) : null; RawProto rpExpand = rp.FindChild("expansion_param"); p.expansion_param = (rpExpand != null) ? ExpansionParameter.FromProto(rpExpand) : null; RawProto rpEmitCon = rp.FindChild("emit_constraint"); p.emit_constraint = (rpEmitCon != null) ? EmitConstraint.FromProto(rpEmitCon) : null; return(p); }