c# - Working with UMat in Emgu wrapper -
i have made application apply hsv filters image , try track specific color. want use umat because need computation of image in gpu , not in cpu instead.
in code below first take image<bgra, byte>
, convert umat
format hsv color format. however, when split channels 3 channels each channel (ex. the hsvchannels[0] has 3 channels; don't know why happening). can't apply filters because when use inrangeimage
method image 1 channel , error form cvinvoke.copy
"unknown array format".
the application not best, want first understand how umat image format works , try improve it.
private umat cvandhsvimage(image<bgra, byte> imgframe, byte lowerhue, byte upperhue, byte lowersat, byte uppersat, byte lowerbright, byte upperbright, byte erosion = 0, byte dilate = 0, bool hue = false, bool sat = false, bool bright = false, bool invert = false) { // first convert input image hsv can change channels //image<hsv, byte> hsvimage = imgframe.convert<hsv, byte>(); umat hsvimage = new umat(); umat bgrimage = new umat(); cvinvoke.cvtcolor(imgframe, bgrimage, colorconversion.bgra2bgr); cvinvoke.cvtcolor(bgrimage, hsvimage, colorconversion.bgr2hsv); // final image returned. umat resultimage = new umat(); umat resultimageh = new umat(); umat resultimages = new umat(); umat resultimagev = new umat(); umat[] hsvchannels = new umat[3]; hsvchannels = hsvimage.split(); umat img1 = inrangeimage(hsvchannels[0], lowerhue, upperhue); umat img2 = inrangeimage(hsvchannels[1], lowersat, uppersat); umat img3 = inrangeimage(hsvchannels[2], lowerbright, upperbright); #region checkbox color mode // evaluation of check box each filter. return right image if (hue) { cvinvoke.cvcopy(img1, resultimageh, intptr.zero); } if (sat) //resultimages = img2; cvinvoke.cvcopy(img2, resultimages, intptr.zero); if (bright) //resultimagev = img3; cvinvoke.cvcopy(img3, resultimages, intptr.zero); if (hue && !sat && !bright) resultimage = resultimageh; if (!hue && sat && !bright) resultimage = resultimages; if (!hue && !sat && bright) resultimage = resultimagev; if (hue && sat && !bright) { cvinvoke.bitwiseand(resultimageh, resultimages, resultimageh); resultimage = resultimageh; } if (hue && !sat && bright) { cvinvoke.bitwiseand(resultimageh, resultimagev, resultimageh); resultimage = resultimageh; } if (!hue && sat && bright) { cvinvoke.bitwiseand(resultimages, resultimagev, resultimages); resultimage = resultimages; } if (hue && sat && bright) { cvinvoke.bitwiseand(resultimageh, resultimages, resultimageh); cvinvoke.bitwiseand(resultimageh, resultimagev, resultimageh); resultimage = resultimageh; } #endregion umat grayimage = new umat(); cvinvoke.cvtcolor(resultimage, bgrimage, colorconversion.hsv2bgr); cvinvoke.cvtcolor(bgrimage, grayimage, colorconversion.bgr2gray); hsvimage.dispose(); bgrimage.dispose(); return grayimage; } /// <summary> /// method define upper , lower values of channels of hsv image /// </summary> /// <param name="hsvimage">image in hsv , byte format</param> /// <param name="lower">lower value applied</param> /// <param name="upper">upper value applied</param> /// <returns>grayscale image applied range</returns> private umat inrangeimage(umat hsvimage, int lower, int upper) { umat resultimage = new umat(); umat lowerborder = new umat(hsvimage.rows, hsvimage.cols, depthtype.cv8u, 3); umat upperborder = new umat(hsvimage.rows, hsvimage.cols, depthtype.cv8u, 3); lowerborder.setto(new gray(lower).mcvscalar); upperborder.setto(new gray(upper).mcvscalar); cvinvoke.inrange(hsvimage, lowerborder, upperborder, resultimage); // dispose image due causing memory leaking. lowerborder.dispose(); upperborder.dispose(); return resultimage; }
it looks bug me in emgu.cv, see same behavior.
try using cvinvoke.split() instead so:
private umat cvandhsvimage(image<bgra, byte> imgframe, byte lowerhue, byte upperhue, byte lowersat, byte uppersat, byte lowerbright, byte upperbright, byte erosion = 0, byte dilate = 0, bool hue = false, bool sat = false, bool bright = false, bool invert = false) { // <snip> // final image returned. umat resultimage = new umat(); umat resultimageh = new umat(); umat resultimages = new umat(); umat resultimagev = new umat(); // << replaced >> // umat[] hsvchannels = new umat[3]; // hsvchannels = hsvimage.split(); // << >> vectorofumat hsvchannels = new vectorofumat(); cvinvoke.split(hsvimage, hsvchannels); // </snip> }
this method seems give cv_8uc1 umats expected.
Comments
Post a Comment