In my open source project ( https://github.com/mmj-the-fighter/GraphicsLabFramework ) i am trying to add a image smoothening box filter for NxN kernel size. I have already implemented the algorithm for 3x3 kernel size. As you can see from the source code below I am not processing the image for edges. Using this logic, for a 5x5 kernel size I have to skip two rows or columns from top, right, bottom and left of the image. So the edges will not be blurred. Is there any other solution.
Here is the code:
/*applying a box filter of size 3x3*/
void blur_image(unsigned char *img, int width, int height)
{
int n = width * height;
int i, j;
int r, g, b;
int x, y;
float v = 1.0 / 9.0;
float kernel[3][3] =
{
{ v, v, v },
{ v, v, v },
{ v, v, v }
};
unsigned char* resimage = (unsigned char *)malloc(width * height * 4 * sizeof(unsigned char));
memcpy(resimage, img, width*height * 4);
for (x = 1; x < width - 1; ++x) {
for (y = 1; y < height - 1; ++y) {
float bs = 0.0;
float gs = 0.0;
float rs = 0.0;
for (i = -1; i <= 1; ++i) {
for (j = -1; j <= 1; ++j){
float weight = (float)kernel[i + 1][j + 1];
unsigned char* buffer = img + width * 4 * (y + j) + (x + i) * 4;
bs += weight * *buffer;
gs += weight * *(buffer + 1);
rs += weight * *(buffer + 2);
}
}
unsigned char* outbuffer = resimage + width * 4 * y + x * 4;
*outbuffer = bs;
*(outbuffer + 1) = gs;
*(outbuffer + 2) = rs;
*(outbuffer + 3) = 255;
}
}
memcpy(img, resimage, width*height * 4);
free(resimage);
}
I use the following structures to load in memory a bmp image:
// header
typedef struct {
uint16_t type; // Magic identifier
uint32_t size; // File size in bytes
uint16_t reserved1; // Not used
uint16_t reserved2; // Not used
uint32_t offset;
uint32_t header_size; // Header size in bytes
uint32_t width; // Width of the image
uint32_t height; // Height of image
uint16_t planes; // Number of color planes
uint16_t bits; // Bits per pixel
uint32_t compression;// Compression type
uint32_t imagesize; // image size in bytes
uint32_t xresol; // pixels per meter
uint32_t yresol; // pixels per meter
uint32_t ncolours; // nr of colours
uint32_t importantcolours; // important colours
} BMP_Header;
// image details
typedef struct {
BMP_Header header;
uint64_t data_size;
uint64_t width;
uint64_t height;
uint8_t *data;// allocate memory based on width and height
} BMP_Image;
Then I want to apply a gaussian filter over it.
The functions associated is the following:
double gaussianModel(double x, double y, double variance) {
return 1 / (2 * 3.14159 * pow(variance, 2)) * exp(-(x * x + y * y) / (2 * variance * variance));
}
double *generate_weights(int radius, double variance, int bits_nr) {
double *weights = (double*)malloc(sizeof(double) * radius * radius * bits_nr);
double sum = 0;
for (int i = 0; i < radius; i++) {
for (int j = 0; j < radius * bits_nr; j++) {
weights[i * radius * bits_nr + j] = gaussianModel(i - radius / 2, j - radius / 2, variance);
sum += weights[i * radius + j];
}
}
// normalize
for (int i = 0; i < radius * radius; i++)
weights[i] /= sum;
return weights;
}
double getWeightedColorValue(double *w, int len, unsigned int index, unsigned int bits_nr) {
double sum = 0;
for (int i = index; i < len; i+= bits_nr)
sum += w[i];
return sum;
}
BMP_Image* BMP_blur_collapsed(BMP_Image *img, unsigned int bits_nr, unsigned int radius, unsigned int th_number, FILE* f) {
BMP_Image *bluredImg = malloc(sizeof(BMP_Image));
bluredImg->header = img->header;
bluredImg->data_size = (img->header.size - sizeof(BMP_Header)) * bits_nr;
bluredImg->width = img->header.width;
bluredImg->height = img->header.height;
bluredImg->data = malloc(sizeof(uint8_t) * bluredImg->data_size);
for(uint64_t i = 0; i < bluredImg->data_size; ++i)
bluredImg->data[i] = img->data[i];
double variance = 1.94;
double* weights = generate_weights(radius, variance, bits_nr);
uint64_t i, j;
double start, end;
start = omp_get_wtime();
#pragma omp parallel for private(i, j) collapse(2) schedule(static) num_threads(th_number)
for (i = 0; i < img->height - radius; i++) {
for (j = 0; j < img->width * bits_nr - radius - bits_nr * 2; j+= bits_nr ) {
uint64_t ofs = i * img->width * bits_nr + j;
double *distributedColorRed = (double*)malloc(sizeof(double) * radius * radius * bits_nr);
double *distributedColorGreen = (double*)malloc(sizeof(double) * radius * radius * bits_nr);
double *distributedColorBlue = (double*)malloc(sizeof(double) * radius * radius * bits_nr);
for (int wx = 0; wx < radius; wx++) {
for (int wy = 0; wy < radius * bits_nr; wy += bits_nr) {
uint64_t wofs = wx * img->width * bits_nr + wy;
// double currWeight = weights[wx * radius + wy];
distributedColorRed[wofs] = weights[wx * radius + wy] * img->data[ofs];
distributedColorGreen[wofs + 1] = weights[wx * radius + wy + 1] * img->data[ofs + 1];
distributedColorBlue[wofs + 2] = weights[wx * radius + wy + 2] * img->data[ofs + 2];
}
}
bluredImg->data[ofs] = getWeightedColorValue(distributedColorRed, radius * radius * bits_nr, 0, bits_nr);
bluredImg->data[ofs + 1] = getWeightedColorValue(distributedColorGreen, radius * radius * bits_nr, 1, bits_nr);
bluredImg->data[ofs + 2] = getWeightedColorValue(distributedColorBlue, radius * radius * bits_nr, 2, bits_nr);
free(distributedColorRed);
free(distributedColorBlue);
free(distributedColorGreen);
}
}
end = omp_get_wtime();
fprintf(f, "blur collapsed %f \n", end - start);
free(weights);
return bluredImg;
}
Assuming that img is a BMP_Image object, then img->data has stored all the pixels inside it:
img->data[i] is Red
img->data[i + 1] is Green
img->data[i + 2] is Blue
But the output is not the expected one after I use this function.
Your image convolution with filtering coefficients looks weird.
One is because you use the variable bits_nr
in the calculation which makes the indexing complicated.
It will be more comprehensible to handle the color components r, g, and
b separately.
The variable name variance is not appropriate because variance = sigma ** 2.
You don't need to apply the multiplication with 1/sqrt(2*PI)/sigma
in gaussianModel() because it is cancelled in the normalization.
Here is an example of fully compilable code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#define SIGMA 1.94
#define RADIUS 5
#define INFILE "0Jayx.bmp"
#define OUTFILE "blurred.bmp"
// header
typedef struct __attribute__((__packed__)) {
uint16_t type; // Magic identifier
uint32_t size; // File size in bytes
uint16_t reserved1; // Not used
uint16_t reserved2; // Not used
uint32_t offset;
uint32_t header_size; // Header size in bytes
uint32_t width; // Width of the image
uint32_t height; // Height of image
uint16_t planes; // Number of color planes
uint16_t bits; // Bits per pixel
uint32_t compression;// Compression type
uint32_t imagesize; // image size in bytes
uint32_t xresol; // pixels per meter
uint32_t yresol; // pixels per meter
uint32_t ncolours; // nr of colours
uint32_t importantcolours; // important colours
} BMP_Header;
// image details
typedef struct {
BMP_Header header;
uint64_t width;
uint64_t height;
uint8_t *b;
uint8_t *g;
uint8_t *r;
} BMP_Image;
double gaussianModel(double x, double y, double sigma) {
return 1. / exp(-(x * x + y * y) / (2 * sigma * sigma));
}
double *generate_coeff(int radius, double sigma) {
double *coeff = malloc(sizeof(double) * radius * radius);
double sum = 0;
for (int i = 0; i < radius; i++) {
for (int j = 0; j < radius; j++) {
coeff[i * radius + j] = gaussianModel(i - radius / 2, j - radius / 2, sigma);
sum += coeff[i * radius + j];
}
}
// normalize
for (int i = 0; i < radius * radius; i++)
coeff[i] /= sum;
return coeff;
}
BMP_Image *BMP_blur_collapsed(BMP_Image *img, int radius, double sigma) {
BMP_Image *bimg = malloc(sizeof(BMP_Image));
bimg->header = img->header;
bimg->width = img->header.width;
bimg->height = img->header.height;
bimg->b = malloc(bimg->width * bimg->height);
bimg->g = malloc(bimg->width * bimg->height);
bimg->r = malloc(bimg->width * bimg->height);
int b, g, r;
double *coeff = generate_coeff(radius, sigma);
int i, j, m, n;
for (i = 0; i < img->height - radius; i++) {
for (j = 0; j < img->width - radius; j++) {
b = g = r = 0;
for (m = 0; m < radius; m++) {
for (n = 0; n < radius; n++) {
b += coeff[m * radius + n] * img->b[(i + m) * img->width + (j + n)];
g += coeff[m * radius + n] * img->g[(i + m) * img->width + (j + n)];
r += coeff[m * radius + n] * img->r[(i + m) * img->width + (j + n)];
}
}
bimg->b[i * bimg->width + j] = b;
bimg->g[i * bimg->width + j] = g;
bimg->r[i * bimg->width + j] = r;
}
}
free(coeff);
return bimg;
}
void free_img(BMP_Image *img)
{
free(img->b);
free(img->g);
free(img->r);
free(img);
}
BMP_Image *read_bmp_file(char *filename)
{
FILE *fp;
int i, j, bytesperline;
BMP_Image *img;
img = malloc(sizeof(BMP_Image));
if (NULL == (fp = fopen(filename, "r"))) {
perror(filename);
exit(1);
}
fread(&img->header, sizeof(char), sizeof(BMP_Header), fp);
img->width = img->header.width;
img->height = img->header.height;
bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
img->b = malloc(img->width * img->height);
img->g = malloc(img->width * img->height);
img->r = malloc(img->width * img->height);
for (i = 0; i < img->height; i++) {
for (j = 0; j < img->width; j++) {
img->b[i * img->width + j] = getc(fp);
img->g[i * img->width + j] = getc(fp);
img->r[i * img->width + j] = getc(fp);
}
for (j = img->width * 3; j < bytesperline; j++) {
getc(fp);
}
}
return img;
}
void write_bmp_file(BMP_Image *img, char *filename)
{
FILE *fp;
int i, j, bytesperline;
if (NULL == (fp = fopen(filename, "w"))) {
perror(filename);
exit(1);
}
bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
fwrite(&img->header, sizeof(char), sizeof(BMP_Header), fp);
for (i = 0; i < img->height; i++) {
for (j = 0; j < img->width; j++) {
putc(img->b[i * img->width + j], fp);
putc(img->g[i * img->width + j], fp);
putc(img->r[i * img->width + j], fp);
}
for (j = img->width * 3; j < bytesperline; j++) {
putc(0, fp);
}
}
}
int main()
{
BMP_Image *img = read_bmp_file(INFILE);
BMP_Image *bimg = BMP_blur_collapsed(img, RADIUS, SIGMA);
write_bmp_file(bimg, OUTFILE);
free_img(img);
free_img(bimg);
return 0;
}
The produced image with radius=5, sigma=1.94:
[Edit]
To modify the code to support 32bit bmp file:
remove the bytesperline relevant codes.
append uint8_t *a; to the struct BMP_Image.
find the b, g, r pixel processing codes and append the a processing
thereafter (just by changing the variable name).
If you are familiar with the patch command, below is the patch file
which can be applied with:
patch -u < gauss.diff
to convert my previous source code to the 32bit version.
(You will need to modify the filenames in the 1st and the 2nd line
according to the source filename you work with.)
gauss.diff:
-- gauss.c.O 2021-12-09 08:57:36.504685533 +0900
+++ gauss.c 2021-12-09 09:49:57.342895501 +0900
## -36,6 +36,7 ##
uint8_t *b;
uint8_t *g;
uint8_t *r;
+ uint8_t *a;
} BMP_Image;
double gaussianModel(double x, double y, double sigma) {
## -67,25 +68,28 ##
bimg->b = malloc(bimg->width * bimg->height);
bimg->g = malloc(bimg->width * bimg->height);
bimg->r = malloc(bimg->width * bimg->height);
+ bimg->a = malloc(bimg->width * bimg->height);
- int b, g, r;
+ int b, g, r, a;
double *coeff = generate_coeff(radius, sigma);
int i, j, m, n;
for (i = 0; i < img->height - radius; i++) {
for (j = 0; j < img->width - radius; j++) {
- b = g = r = 0;
+ b = g = r = a = 0;
for (m = 0; m < radius; m++) {
for (n = 0; n < radius; n++) {
b += coeff[m * radius + n] * img->b[(i + m) * img->width + (j + n)];
g += coeff[m * radius + n] * img->g[(i + m) * img->width + (j + n)];
r += coeff[m * radius + n] * img->r[(i + m) * img->width + (j + n)];
+ a += coeff[m * radius + n] * img->r[(i + m) * img->width + (j + n)];
}
}
bimg->b[i * bimg->width + j] = b;
bimg->g[i * bimg->width + j] = g;
bimg->r[i * bimg->width + j] = r;
+ bimg->a[i * bimg->width + j] = a;
}
}
free(coeff);
## -98,13 +102,15 ##
free(img->b);
free(img->g);
free(img->r);
+ free(img->a);
free(img);
}
BMP_Image *read_bmp_file(char *filename)
{
FILE *fp;
- int i, j, bytesperline;
+// int i, j, bytesperline;
+ int i, j;
BMP_Image *img;
img = malloc(sizeof(BMP_Image));
## -117,21 +123,25 ##
img->width = img->header.width;
img->height = img->header.height;
- bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
+// bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
img->b = malloc(img->width * img->height);
img->g = malloc(img->width * img->height);
img->r = malloc(img->width * img->height);
+ img->a = malloc(img->width * img->height);
for (i = 0; i < img->height; i++) {
for (j = 0; j < img->width; j++) {
img->b[i * img->width + j] = getc(fp);
img->g[i * img->width + j] = getc(fp);
img->r[i * img->width + j] = getc(fp);
+ img->a[i * img->width + j] = getc(fp);
}
+/*
for (j = img->width * 3; j < bytesperline; j++) {
getc(fp);
}
+*/
}
return img;
}
## -139,13 +149,14 ##
void write_bmp_file(BMP_Image *img, char *filename)
{
FILE *fp;
- int i, j, bytesperline;
+// int i, j, bytesperline;
+ int i, j;
if (NULL == (fp = fopen(filename, "w"))) {
perror(filename);
exit(1);
}
- bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
+// bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
fwrite(&img->header, sizeof(char), sizeof(BMP_Header), fp);
for (i = 0; i < img->height; i++) {
## -153,10 +164,13 ##
putc(img->b[i * img->width + j], fp);
putc(img->g[i * img->width + j], fp);
putc(img->r[i * img->width + j], fp);
+ putc(img->a[i * img->width + j], fp);
}
+/*
for (j = img->width * 3; j < bytesperline; j++) {
putc(0, fp);
}
+*/
}
}
I have this code that's very messy and there are two structs, both defined and initialized the same. However for the tall struct I can store variables in the struct tall[radius] without any issues. But when I replicate the process for xx struct it doenst work prints wrong values.
I can't seem to figure out what's wrong with the struct usage.
I need an array of structs to store a different sized array dynamically every time, and other elements later for each struct.
I'm open to new approaches, too.
Why are the two structs performing differently?
#include <stdio.h>
#include <stdlib.h>
#define ar_length 18 //this is the radius max
#define WIDTH 10 //xx width
struct ttall
{
int *pnt;
};
struct xall
{
int *pnt;
};
int main()
{
int i;
int m;
int *x1;
int *x2;
int *x3;
int *ttThis;
int rad_size;
//beginning of the loop
int radius = 1;
int size = (2 * radius + 1);
int size_sqrd = size * size * size;
struct ttall **tall = malloc(sizeof(struct ttall *));
struct ttall *struct_pnt = malloc( 3*sizeof(struct ttall));
struct xall **xx = malloc(sizeof(struct xall *));
struct xall *xpnt = malloc( 3*sizeof(struct xall));
for (int radius = 0; radius < 3; radius++)
{
//need to increment the pointer to the struct everytime
xx[radius] = xpnt+radius;
tall[radius] = struct_pnt+radius;
int z = -1;
int t = -radius-2;
printf("****T*** %d\n",t);
int rad;
int meshCount;
meshCount = (2 * (radius+1) + 1);
rad_size = (2 * (radius+1) + 1) * (2 * (radius+1) + 1) * (2 * (radius+1) + 1);
printf("radius size : %d\n",rad_size);
printf("mesh size : %d\n",meshCount);
tall[radius]->pnt = malloc(rad_size * sizeof(int));
xx[radius]->pnt = malloc(rad_size * WIDTH * sizeof(int));
x1 = malloc(rad_size * sizeof(int));
x2 = malloc(rad_size * sizeof(int));
x3 = malloc(rad_size * sizeof(int));
for (i = 0; i < meshCount; i++)
{
t++;
z++;
for (m = 0; m < meshCount*meshCount; m++)
{
x1[z * (meshCount*meshCount) + m] = t;
}
}
//x2 computations
i = 0;
m = 0;
z = 0;
t = -radius-2;
int x;
for (x = 0; x < meshCount; x++)
{
t++;
for (m = 0; m < meshCount; m++)
{
for(int h = 0;h<meshCount;h++){
int index = meshCount*x+(meshCount*meshCount)*h +m ;
x2[index] = t;
}
}
}
//x3 computations
i = 0;
m = 0;
z = 0;
t = -radius-2;
for (x = 0; x < meshCount; x++)
{
// t++;
t = -radius-2;
for (m = 0; m < meshCount; m++)
{
t++;
for(int h = 0;h<meshCount;h++){
int index = meshCount*x+(meshCount*meshCount)*h +m ;
x3[index] = t;
}
}
}
// structure initializations and memalocation
//works fine with expanding radius
for (m = 0; m < rad_size; m++)
{
tall[radius]->pnt[m] = (x1[m] * x1[m]) + (x2[m] * x2[m]) + (x3[m] * x3[m]);
}
// doesnt work here
m = 0;
for (i = 0; i < rad_size; i++)
{
xx[radius]->pnt[i * WIDTH ] = 1;
xx[radius]->pnt[i * WIDTH + 1] = x1[i];
xx[radius]->pnt[i * WIDTH + 2] = x2[i];
xx[radius]->pnt[i * WIDTH + 3] = x3[i];
xx[radius]->pnt[i * WIDTH + 4] = x1[i] * x1[i];
xx[radius]->pnt[i * WIDTH + 5] = x1[i] * x2[i];
xx[radius]->pnt[i * WIDTH + 6] = x1[i] * x3[i];
xx[radius]->pnt[i * WIDTH + 7] = x2[i] * x2[i];
xx[radius]->pnt[i * WIDTH + 8] = x2[i] * x3[i];
xx[radius]->pnt[i * WIDTH + 9] = x3[i] * x3[i];
}
}
//free(x1);
//free(x2);
//free(x3);
//***testing sum***
// the sum when radius = 1 of xx should be 171
int k = 0;
int sum = 0;
//can replace 27 with rad_size
for (k = 0; k < 27*WIDTH; k++)
{
sum = sum + abs(xx[0]->pnt[k]);
//printf("%d\n",abs(xx[0]->pnt[k]));
}
printf(" sum xx : %d\n", sum);
//******Testing****
for (int c = 0; c < 27; c++)
{
//printf("X2 : %d\n",x3[c]);
printf("tall : %d\n", tall[1]->pnt[c]);
//printf("%d\n",xx[c]);
}
//free(ttThis);
//free(xx);
}
With struct ttall **tall = malloc(sizeof(struct ttall *)); you allocate room for one pointer.
But later you index it with tall[radius] but radius is more than 1.
You must allocate more memory:
struct ttall **tall = malloc(3 * sizeof(struct ttall *));`
I am trying to write a for loop in the second version which produce the same result in the original code but i am not sure how to get -400,-200,-400 in sequential order.
original code:
p->m_p[0] = randFloat(-400.0f, 400.0);
p->m_p[1] = randFloat(-200.0f, 200.0);
p->m_p[2] = randFloat(-400.0f, 400.0);
second version:
float x = -800;
float y = 800;
for(int i = 0; i < 4; i++)
{
plNew->m_fPosition[i] = randFloat(x / 2,y / 2);
}
If you need it to work in C (or in C++ before C++11), this would work:
#define NUMBER_OF_VALUES 3
float bounds[NUMBER_OF_VALUES] = { 400.0f, 200.0f, 400.0f };
for (int i = 0; i < NUMBER_OF_VALUES; i++)
{
plNew->m_fPosition[i] = randFloat(-bounds[i], bounds[i]);
}
You can extend this to make NUMBER_OF_VALUES be 4 or a larger number as long as you initialize all the members of bounds[NUMBER_OF_VALUES] with the desired constants.
A nice feature of this is that the sequence of constants can be anything you like,
not limited to alternating 400, 200, 400 or any other regular sequence.
Something like this?
for (int i = 0; i < 4; i++) {
float x, y;
if (i % 2) {
x = -400.0f;
y = 400.0f;
} else {
x = -200.0f;
y = 200.0f;
}
p->m_p[i] = randFloat(x, y);
}
What about?
float x = -800;
float y = 800;
for(int i = 0; i < 4; i++)
{
float z = 2.0 * ((float)((i + 1) % 2 + 1));
plNew->m_fPosition[i] = randFloat(x / z, y / z);
}
I would suggest keeping it simple, using something like the following :
const float arr3[] = {-400.0f, -200.0f, -400.0f};
for(int i = 0; i < 3; i++)
{
plNew->m_fPosition[i] = arr3[i];
}
float x = -400;
float y = 400;
for(int i = 0; i < 3; i++)
{
plNew->m_fPosition[i] = randFloat(x / (1 + (i & 1)), y / (1 + (i & 1)));
}
I am converting an image in YUV420 format to RGB image in opencv but im getting an Orange colored image after conversion. I used following code to do that. Is there any problem in my code ??
int step = origImage->widthStep;
uchar *data = (uchar *)origImage->imageData;
int size = origImage->width * origImage->height;
IplImage* img1 = cvCreateImage(cvGetSize(origImage), IPL_DEPTH_8U, 3);
for (int i = 0; i<origImage->height; i++)
{
for (int j=0; j<origImage->width; j++)
{
float Y = data[i*step + j];
float U = data[ (int)(size + (i/2)*(step/2) + j/2) ];
float V = data[ (int)(size*1.25 + (i/2)*(step/2) + j/2)];
float R = Y + (int)(1.772f*V);
float G = Y - (int)(0.344f*V + 0.714f*U);
float B = Y + (int)(1.402f*U);
if (R < 0){ R = 0; } if (G < 0){ G = 0; } if (B < 0){ B = 0; }
if (R > 255 ){ R = 255; } if (G > 255) { G = 255; } if (B > 255) { B = 255; }
cvSet2D(img1, i, j,cvScalar(B,G,R));
}
}
origImage -> YUV image,
img1 -> RGB image,
http://upload.wikimedia.org/wikipedia/en/0/0d/Yuv420.svg
Is there any opencv function which can convert a pixel in YUV420 format to corresponding RGB pixel ? (not entire image)
I got answer by modifying the formula for calculating R G B values,
This code is working fine
int step = origImage->widthStep;
uchar *data = (uchar *)origImage->imageData;
int size = origImage->width * origImage->height;
IplImage* img1 = cvCreateImage(cvGetSize(origImage), IPL_DEPTH_8U, 3);
for (int i = 0; i<origImage->height; i++)
{
for (int j=0; j<origImage->width; j++)
{
float Y = data[i*step + j];
float U = data[ (int)(size + (i/2)*(step/2) + j/2) ];
float V = data[ (int)(size*1.25 + (i/2)*(step/2) + j/2)];
float R = Y + 1.402 * (V - 128);
float G = Y - 0.344 * (U - 128) - 0.714 * (V - 128);
float B = Y + 1.772 * (U - 128);
if (R < 0){ R = 0; } if (G < 0){ G = 0; } if (B < 0){ B = 0; }
if (R > 255 ){ R = 255; } if (G > 255) { G = 255; } if (B > 255) { B = 255; }
cvSet2D(img1, i, j,cvScalar(B,G,R));
}
}
the 1st problem is using the outdated c-api (it's dead & gone. please use c++ instead).
the 2nd problem is writing your own (slow and error prone) pixel loops
why not use :
cvtColor(crs,dst, CV_YUV2BGR); // or CV_YUV2BGR_I420
instead ?