/// <summary> /// Resize the CudaImage. The calling GpuMat be GpuMat%lt;Byte>. If stream is specified, it has to be either 1 or 4 channels. /// </summary> /// <param name="size">The new size</param> /// <param name="interpolationType">The interpolation type</param> /// <param name="stream">Use a Stream to call the function asynchronously (non-blocking) or null to call the function synchronously (blocking).</param> /// <returns>A CudaImage of the new size</returns> public CudaImage <TColor, TDepth> Resize(Size size, CvEnum.Inter interpolationType, Stream stream = null) { CudaImage <TColor, TDepth> result = new CudaImage <TColor, TDepth>(size); CudaInvoke.Resize(this, result, size, 0, 0, interpolationType, stream); return(result); }
private static void ConvertColor(IInputArray src, IOutputArray dest, Type srcColor, Type destColor, int dcn, Size size, Stream stream) { try { // if the direct conversion exist, apply the conversion CudaInvoke.CvtColor(src, dest, CvToolbox.GetColorCvtCode(srcColor, destColor), dcn, stream); } catch { try { //if a direct conversion doesn't exist, apply a two step conversion //in this case, needs to wait for the completion of the stream because a temporary local image buffer is used //we don't want the tmp image to be released before the operation is completed. using (CudaImage <Bgr, TDepth> tmp = new CudaImage <Bgr, TDepth>(size)) { CudaInvoke.CvtColor(src, tmp, CvToolbox.GetColorCvtCode(srcColor, typeof(Bgr)), 3, stream); CudaInvoke.CvtColor(tmp, dest, CvToolbox.GetColorCvtCode(typeof(Bgr), destColor), dcn, stream); stream.WaitForCompletion(); } } catch (Exception excpt) { throw new NotSupportedException(String.Format( "Conversion from CudaImage<{0}, {1}> to CudaImage<{2}, {3}> is not supported by OpenCV: {4}", srcColor.ToString(), typeof(TDepth).ToString(), destColor.ToString(), typeof(TDepth).ToString(), excpt.Message)); } } }
/// <summary> /// Create a clone of this CudaImage /// </summary> /// <param name="stream">Use a Stream to call the function asynchronously (non-blocking) or null to call the function synchronously (blocking).</param> /// <returns>A clone of this CudaImage</returns> public CudaImage <TColor, TDepth> Clone(Stream stream) { CudaImage <TColor, TDepth> result = new CudaImage <TColor, TDepth>(Size); CopyTo(result, null, stream); return(result); }
///<summary> Convert the current CudaImage to the specific color and depth </summary> ///<typeparam name="TOtherColor"> The type of color to be converted to </typeparam> ///<typeparam name="TOtherDepth"> The type of pixel depth to be converted to </typeparam> ///<returns>CudaImage of the specific color and depth </returns> public CudaImage <TOtherColor, TOtherDepth> Convert <TOtherColor, TOtherDepth>() where TOtherColor : struct, IColor where TOtherDepth : new() { CudaImage <TOtherColor, TOtherDepth> res = new CudaImage <TOtherColor, TOtherDepth>(Size); res.ConvertFrom(this); return(res); }
/// <summary> /// Create a CudaImage from the specific region of <paramref name="image"/>. The data is shared between the two CudaImage /// </summary> /// <param name="image">The CudaImage where the region is extracted from</param> /// <param name="colRange">The column range. Use MCvSlice.WholeSeq for all columns.</param> /// <param name="rowRange">The row range. Use MCvSlice.WholeSeq for all rows.</param> public CudaImage(CudaImage <TColor, TDepth> image, Range rowRange, Range colRange) : this(CudaInvoke.GetRegion(image, ref rowRange, ref colRange), true) { }
/// <summary> /// Convert the source image to the current image, if the size are different, the current image will be a resized version of the srcImage. /// </summary> /// <typeparam name="TSrcColor">The color type of the source image</typeparam> /// <typeparam name="TSrcDepth">The color depth of the source image</typeparam> /// <param name="srcImage">The sourceImage</param> public void ConvertFrom <TSrcColor, TSrcDepth>(CudaImage <TSrcColor, TSrcDepth> srcImage) where TSrcColor : struct, IColor where TSrcDepth : new() { if (!Size.Equals(srcImage.Size)) { //if the size of the source image do not match the size of the current image using (CudaImage <TSrcColor, TSrcDepth> tmp = srcImage.Resize(Size, Emgu.CV.CvEnum.Inter.Linear, null)) { ConvertFrom(tmp); return; } } if (typeof(TColor) == typeof(TSrcColor)) { #region same color if (typeof(TDepth) == typeof(TSrcDepth)) //same depth { srcImage.CopyTo(this); } else //different depth { if (typeof(TDepth) == typeof(Byte) && typeof(TSrcDepth) != typeof(Byte)) { double[] minVal, maxVal; Point[] minLoc, maxLoc; srcImage.MinMax(out minVal, out maxVal, out minLoc, out maxLoc); double min = minVal[0]; double max = maxVal[0]; for (int i = 1; i < minVal.Length; i++) { min = Math.Min(min, minVal[i]); max = Math.Max(max, maxVal[i]); } double scale = 1.0, shift = 0.0; if (max > 255.0 || min < 0) { scale = (max == min) ? 0.0 : 255.0 / (max - min); shift = (scale == 0) ? min : -min * scale; } srcImage.ConvertTo(this, CvInvoke.GetDepthType(typeof(TDepth)), scale, shift, null); } else { srcImage.ConvertTo(this, CvInvoke.GetDepthType(typeof(TDepth)), 1.0, 0.0, null); //CudaInvoke.ConvertTo(srcImage.Ptr, Ptr, 1.0, 0.0, IntPtr.Zero); } } #endregion } else { #region different color if (typeof(TDepth) == typeof(TSrcDepth)) { //same depth ConvertColor(srcImage, this, typeof(TSrcColor), typeof(TColor), NumberOfChannels, Size, null); } else { //different depth using (CudaImage <TSrcColor, TDepth> tmp = srcImage.Convert <TSrcColor, TDepth>()) //convert depth ConvertColor(tmp, this, typeof(TSrcColor), typeof(TColor), NumberOfChannels, Size, null); } #endregion } }