richard-to
4/7/2014 - 12:16 PM

## Basic implementations of gaussian blur, scaling image using linear interpolation, and shrinking an image by simple resampling

Basic implementations of gaussian blur, scaling image using linear interpolation, and shrinking an image by simple resampling

``````#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#define WINDOW_TITLE "Gaussian Blur"
#define IMAGE "chugach-mtns.jpg"
#define SIGMA 1.0

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{
namedWindow(WINDOW_TITLE, WINDOW_AUTOSIZE);

Mat blur = Mat::zeros(src.rows, src.cols, CV_8UC3);

double kernel[3][3];
double sum = 0;
double sigFactor = 1.0 / (2.0 * M_PI * SIGMA * SIGMA);

// Calculate 3x3 kernel given sigma
for (int x = 0; x < 3; ++x) {
int xdist = abs(x - 1);
int xdistsq = xdist * xdist;
for (int y = 0; y < 3; ++y) {
int ydist = abs(y - 1);
int ydistsq = ydist * ydist;
kernel[x][y] = sigFactor * exp(-((xdist + ydistsq) / (2.0 * SIGMA * SIGMA)));
sum += kernel[x][y];
}
}

// Normalize Sigma
for (int x = 0; x < 3; ++x) {
for (int y = 0; y < 3; ++y) {
kernel[x][y] = kernel[x][y] / sum;
}
}

// Log Kernel for Sanity Check
for (int x = 0; x < 3; ++x) {
printf("%f %f %f\n", kernel[x][0], kernel[x][1], kernel[x][2]);
}

// Apply kernel
for (int i = 1; i < blur.rows - 1; ++i) {
for (int j = 1; j < blur.cols - 1; ++j) {
Vec3b p0 = src.at<Vec3b>(i - 1, j - 1);
Vec3b p1 = src.at<Vec3b>(i - 1, j);
Vec3b p2 = src.at<uchar>(i - 1, j + 1);

Vec3b p3 = src.at<Vec3b>(i, j - 1);
Vec3b p4 = src.at<Vec3b>(i, j);
Vec3b p5 = src.at<Vec3b>(i, j + 1);

Vec3b p6 = src.at<Vec3b>(i + 1, j - 1);
Vec3b p7 = src.at<Vec3b>(i + 1, j);
Vec3b p8 = src.at<Vec3b>(i + 1, j + 1);

double r =
p0[0] * kernel[0][0] + p1[0] * kernel[0][1] + p2[0] * kernel[0][2] +
p3[0] * kernel[1][0] + p4[0] * kernel[1][1] + p5[0] * kernel[1][2] +
p6[0] * kernel[2][0] + p7[0] * kernel[2][1] + p8[0] * kernel[2][2];

double g =
p0[1] * kernel[0][0] + p1[1] * kernel[0][1] + p2[1] * kernel[0][2] +
p3[1] * kernel[1][0] + p4[1] * kernel[1][1] + p5[1] * kernel[1][2] +
p6[1] * kernel[2][0] + p7[1] * kernel[2][1] + p8[1] * kernel[2][2];

double b =
p0[2] * kernel[0][0] + p1[2] * kernel[0][1] + p2[2] * kernel[0][2] +
p3[2] * kernel[1][0] + p4[2] * kernel[1][1] + p5[2] * kernel[1][2] +
p6[2] * kernel[2][0] + p7[2] * kernel[2][1] + p8[2] * kernel[2][2];

Vec3b q0;
q0[0] = r;
q0[1] = g;
q0[2] = b;

blur.at<Vec3b>(i, j) = q0;
}
}
imshow(WINDOW_TITLE, blur);
waitKey(0);
}``````
``````#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#define WINDOW_TITLE "2x Scale Down"
#define IMAGE "chugach-mtns.jpg"

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{
namedWindow(WINDOW_TITLE, WINDOW_AUTOSIZE);

Mat scaled = Mat::zeros(src.rows / 2, src.cols / 2, CV_8UC3);

for (int i = 0; i < scaled.rows; ++i) {
for (int j = 0; j < scaled.cols; ++j) {
scaled.at<Vec3b>(i, j) = src.at<Vec3b>(i * 2, j * 2);
}
}
imshow(WINDOW_TITLE, scaled);
waitKey(0);
}``````
``````#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#define WINDOW_TITLE "2x Scale Up"
#define IMAGE "chugach-mtns.jpg"

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{
namedWindow(WINDOW_TITLE, WINDOW_AUTOSIZE);

Mat scaled = Mat::zeros(src.rows * 2, src.cols * 2, CV_8UC3);
Vec3b p0;
Vec3b p1;
Vec3b pInterpolated;

for (int i = 0; i < src.rows; ++i) {
for (int j = 0; j < src.cols; ++j) {
scaled.at<Vec3b>(i * 2, j * 2) = src.at<Vec3b>(i, j);

if (i + 1 == src.rows) {
scaled.at<Vec3b>(i * 2 + 1, j * 2) = src.at<Vec3b>(i, j);
} else {
p0 = src.at<Vec3b>(i, j);
p1 = src.at<Vec3b>(i + 1, j);
pInterpolated.val[0] = p0.val[0] + (p1.val[0] - p0.val[0]) * 0.5;
pInterpolated.val[1] = p0.val[1] + (p1.val[1] - p0.val[1]) * 0.5;
pInterpolated.val[2] = p0.val[2] + (p1.val[2] - p0.val[2]) * 0.5;
scaled.at<Vec3b>(i * 2 + 1, j * 2)  = pInterpolated;
}

if (j + 1 == src.cols) {
scaled.at<Vec3b>(i * 2, j * 2 + 1) = src.at<Vec3b>(i, j);
} else {
p0 = src.at<Vec3b>(i, j);
p1 = src.at<Vec3b>(i, j + 1);
pInterpolated.val[0] = p0.val[0] + (p1.val[0] - p0.val[0]) * 0.5;
pInterpolated.val[1] = p0.val[1] + (p1.val[1] - p0.val[1]) * 0.5;
pInterpolated.val[2] = p0.val[2] + (p1.val[2] - p0.val[2]) * 0.5;
scaled.at<Vec3b>(i * 2, j * 2 + 1)  = pInterpolated;
}

if (i + 1 == src.rows || j + 1 == src.cols) {
scaled.at<Vec3b>(i * 2 + 1, j * 2 + 1) = src.at<Vec3b>(i, j);
} else {
p0 = src.at<Vec3b>(i, j);
p1 = src.at<Vec3b>(i + 1, j + 1);
pInterpolated.val[0] = p0.val[0] + (p1.val[0] - p0.val[0]) * 0.5;
pInterpolated.val[1] = p0.val[1] + (p1.val[1] - p0.val[1]) * 0.5;
pInterpolated.val[2] = p0.val[2] + (p1.val[2] - p0.val[2]) * 0.5;
scaled.at<Vec3b>(i * 2 + 1, j * 2 + 1)  = pInterpolated;
}
}
}
imshow(WINDOW_TITLE, scaled);
waitKey(0);
}``````