Skip to content

Instantly share code, notes, and snippets.

@richard-to
Created April 7, 2014 12:16
Show Gist options
  • Save richard-to/10019190 to your computer and use it in GitHub Desktop.
Save richard-to/10019190 to your computer and use it in GitHub Desktop.
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 src = imread(IMAGE);
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 src = imread(IMAGE);
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 src = imread(IMAGE);
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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment