c++ - Pixels in YUV image -
i using opencv achieve object tracking. read yuv image better option use rgb image. problem fail understand yuv format although spend time read notes. y brightness believe calculated combination of r, g, b component.
my main problem how can access , manipulate pixels in yuv image format. in rgb format easy access component , therefore change using simple operatin
src.at<vec3b>(j,i).val[0] = 0; example
but not case in yuv. need in accessing , changing pixel values in yuv image. example if pixel in rgb red, want keep corresponding pixel in yuv , rest removed. please me this.
i suggest operating on image in hsv or lab rather rgb.
the raw image camera in ycbcr (sometimes called yuv, think incorrect, may wrong), , laid out in way resembles yuyv (repeating), if can convert directly hsv, avoid additional copy , conversion operations save time. may matter if you're processing video or batches of images however.
here's c++ code converting between ycbcr , rgb (one uses integer math, other floating point):
colour::bgr colour::ycbcr::tobgrint() const { int c0 = 22987; int c1 = -11698; int c2 = -5636; int c3 = 29049; int y = this->y; int cb = this->cb - 128; int cr = this->cr - 128; int b = y + (((c3 * cb) + (1 << 13)) >> 14); int g = y + (((c2 * cb + c1 * cr) + (1 << 13)) >> 14); int r = y + (((c0 * cr) + (1 << 13)) >> 14); if (r < 0) r = 0; else if (r > 255) r = 255; if (g < 0) g = 0; else if (g > 255) g = 255; if (b < 0) b = 0; else if (b > 255) b = 255; return colour::bgr(b, g, r); } colour::bgr colour::ycbcr::tobgrfloat() const { float y = this->y; float cb = this->cb; float cr = this->cr; int r = y + 1.40200 * (cr - 0x80); int g = y - 0.34414 * (cb - 0x80) - 0.71414 * (cr - 0x80); int b = y + 1.77200 * (cb - 0x80); if (r < 0) r = 0; else if (r > 255) r = 255; if (g < 0) g = 0; else if (g > 255) g = 255; if (b < 0) b = 0; else if (b > 255) b = 255; return colour::bgr(b, g, r); }
and conversion bgr hsv:
colour::hsv colour::bgr2hsv(bgr const& in) { colour::hsv out; int const hstep = 255 / 3; // hue step size between red -> green -> blue int min = in.r < in.g ? in.r : in.g; min = min < in.b ? min : in.b; int max = in.r > in.g ? in.r : in.g; max = max > in.b ? max : in.b; out.v = max; // v int chroma = max - min; if (max > 0) { out.s = 255 * chroma / max; // s } else { // r = g = b = 0 // s = 0, v undefined out.s = 0; out.h = 0; out.v = 0; // it's undefined return out; } if (chroma == 0) { out.h = 0; return out; } const int chroma2 = chroma * 2; int offset; int diff; if (in.r == max) { offset = 3 * hstep; diff = in.g - in.b; } else if (in.g == max) { offset = hstep; diff = in.b - in.r; } else { offset = 2 * hstep; diff = in.r - in.g; } int h = offset + (diff * (hstep + 1)) / chroma2; // rotate such red has hue 0 if (h >= 255) h -= 255; assert(h >= 0 && h < 256); out.h = h; return out;
unfortunately not have code in 1 step.
you can use built-in opencv functions colour conversion.
cvtcolor(img, img, cv_bgr2hsv);
Comments
Post a Comment