/// <summary> /// Create a clone of this GpuImage /// </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 GpuImage</returns> public GpuImage <TColor, TDepth> Clone() { GpuImage <TColor, TDepth> result = new GpuImage <TColor, TDepth>(Size); GpuInvoke.Copy(_ptr, result, IntPtr.Zero); return(result); }
/// <summary> /// Makes multi-channel array out of several single-channel arrays /// </summary> ///<param name="gpuMats"> ///An array of single channel GpuMat where each item ///in the array represent a single channel of the GpuMat ///</param> /// <param name="stream">Use a Stream to call the function asynchronously (non-blocking) or null to call the function synchronously (blocking).</param> public void MergeFrom(GpuMat <TDepth>[] gpuMats, Stream stream) { Debug.Assert(NumberOfChannels == gpuMats.Length, "Number of channels does not agrees with the length of gpuMats"); //If single channel, perform a copy if (NumberOfChannels == 1) { if (stream == null) { GpuInvoke.Copy(gpuMats[0].Ptr, _ptr, IntPtr.Zero); } else { stream.Copy <TDepth>(gpuMats[0], this); } } //handle multiple channels Size size = Size; IntPtr[] ptrs = new IntPtr[gpuMats.Length]; for (int i = 0; i < gpuMats.Length; i++) { Debug.Assert(gpuMats[i].Size == size, "Size mismatch"); ptrs[i] = gpuMats[i].Ptr; } GCHandle handle = GCHandle.Alloc(ptrs, GCHandleType.Pinned); GpuInvoke.Merge(handle.AddrOfPinnedObject(), _ptr, stream); handle.Free(); }
///<summary> ///Split current Image into an array of gray scale images where each element ///in the array represent a single color channel of the original image ///</summary> ///<param name="gpuMats"> ///An array of single channel GpuMat where each item ///in the array represent a single channel of the original GpuMat ///</param> /// <param name="stream">Use a Stream to call the function asynchronously (non-blocking) or null to call the function synchronously (blocking).</param> public void SplitInto(GpuMat <TDepth>[] gpuMats, Stream stream) { Debug.Assert(NumberOfChannels == gpuMats.Length, "Number of channels does not agrees with the length of gpuMats"); if (NumberOfChannels == 1) { //If single channel, return a copy if (stream == null) { GpuInvoke.Copy(_ptr, gpuMats[0], IntPtr.Zero); } else { stream.Copy <TDepth>(this, gpuMats[0]); } } else { //handle multiple channels Size size = Size; IntPtr[] ptrs = new IntPtr[gpuMats.Length]; for (int i = 0; i < ptrs.Length; i++) { Debug.Assert(gpuMats[i].Size == size, "Size mismatch"); ptrs[i] = gpuMats[i].Ptr; } GCHandle handle = GCHandle.Alloc(ptrs, GCHandleType.Pinned); GpuInvoke.Split(_ptr, handle.AddrOfPinnedObject(), stream); handle.Free(); } }
/// <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>(GpuImage <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 (GpuImage <TSrcColor, TSrcDepth> tmp = srcImage.Resize(Size, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR, null)) { ConvertFrom(tmp); return; } } if (typeof(TColor) == typeof(TSrcColor)) { #region same color if (typeof(TDepth) == typeof(TSrcDepth)) //same depth { GpuInvoke.Copy(srcImage.Ptr, Ptr, IntPtr.Zero); } 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; } GpuInvoke.ConvertTo(srcImage.Ptr, Ptr, scale, shift); } else { GpuInvoke.ConvertTo(srcImage.Ptr, Ptr, 1.0, 0.0); } } #endregion } else { #region different color if (typeof(TDepth) == typeof(TSrcDepth)) { //same depth ConvertColor(srcImage.Ptr, Ptr, typeof(TSrcColor), typeof(TColor), Size, null); } else { //different depth using (GpuImage <TSrcColor, TDepth> tmp = srcImage.Convert <TSrcColor, TDepth>()) //convert depth ConvertColor(tmp.Ptr, Ptr, typeof(TSrcColor), typeof(TColor), Size, null); } #endregion } }