Skip to content

Instantly share code, notes, and snippets.

@jkawamoto
Last active August 29, 2015 14:25
Show Gist options
  • Save jkawamoto/7aca96b3ac8f96a3d769 to your computer and use it in GitHub Desktop.
Save jkawamoto/7aca96b3ac8f96a3d769 to your computer and use it in GitHub Desktop.
高度プログラミング総合課題 3 サンプルコード

総合課題 3 サンプルコード

共通ファイル

  • image.c: 基本的な画像処理(読み込み,書き出し,フィルタ適用)
  • filter.c: 簡単なフィルタ

サンプル別ファイル

ただし,フィルタそのものは filter.c で定義されている.

  • uniform.c: 平滑化フィルタ
  • gaussian.c: ガウシアンフィルタ
  • sharp.c: 先鋭化フィルタ
  • sepia.c: セピア調に変換
#include <stdio.h>
#include "image.h"
#include "filter.h"
Image *uniform(Image * const image){
Filter * const filter = create_filter(3, 3);
for(int i = 0; i < 9; ++i){
(filter->r)[i] = 1.0 / 9.0;
(filter->g)[i] = 1.0 / 9.0;
(filter->b)[i] = 1.0 / 9.0;
}
apply_filter(image, filter);
delete_filter(filter);
return image;
}
Image *gaussian(Image * const image){
Filter * const filter = create_filter(3, 3);
int i = 0;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 1.0 / 16.0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 2.0 / 16.0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 1.0 / 16.0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 2.0 / 16.0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 4.0 / 16.0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 2.0 / 16.0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 1.0 / 16.0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 2.0 / 16.0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 1.0 / 16.0;
apply_filter(image, filter);
delete_filter(filter);
return image;
}
Image *sharp(Image * const image){
Filter * const filter = create_filter(3, 3);
int i = 0;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 5;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 0;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 0;
apply_filter2(image, filter);
delete_filter(filter);
return image;
}
Image *sharp2(Image * const image){
Filter * const filter = create_filter(3, 3);
int i = 0;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = 9;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
++i;
(filter->r)[i] = (filter->g)[i] = (filter->b)[i] = -1;
apply_filter2(image, filter);
delete_filter(filter);
return image;
}
#ifndef _FILTER_H_
#define _FILTER_H_
Image *uniform(Image * const image);
Image *gaussian(Image * const image);
Image *sharp(Image * const image);
Image *sharp2(Image * const image);
#endif
#include <stdio.h>
#include "image.h"
#include "filter.h"
int main(){
Image *image;
FILE *fin, *fout;
// Read an image.
fin = fopen("scene.ppm", "r");
if(fin == NULL){
printf("File not found.\n");
return 1;
}
image = read_image(fin);
fclose(fin);
// Do something.
gaussian(image);
// Write an image.
fout = fopen("gaussian.ppm", "wb");
write_image(fout, image);
delete_image(image);
fclose(fout);
return 0;
}
#include "image.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
uchar _round(int v){
if(v < 0){
return 0;
}else if(v > 255){
return 255;
}
return v;
}
int min(const int a, const int b){
if(a < b){
return a;
}else{
return b;
}
}
int max(const int a, const int b){
if(a > b){
return a;
}else{
return b;
}
}
Image *create_image(const int width, const int height){
const int size = width * height;
Image * const res = malloc(sizeof(Image));
res->width = width;
res->height = height;
res->r = malloc(sizeof(uchar) * size);
res->g = malloc(sizeof(uchar) * size);
res->b = malloc(sizeof(uchar) * size);
return res;
}
void delete_image(Image * const image){
free(image->r);
free(image->g);
free(image->b);
free(image);
}
Image *copy_image(const Image * const image){
Image * const res = create_image(image->width, image->height);
const int size = image->width * image->height;
memcpy(res->r, image->r, sizeof(uchar) * size);
memcpy(res->g, image->g, sizeof(uchar) * size);
memcpy(res->b, image->b, sizeof(uchar) * size);
return res;
}
Filter *create_filter(const int width, const int height){
const int size = width * height;
Filter * const res = malloc(sizeof(Filter));
res->width = width;
res->height = height;
res->r = malloc(sizeof(float) * size);
res->g = malloc(sizeof(float) * size);
res->b = malloc(sizeof(float) * size);
return res;
}
void delete_filter(Filter * const filter){
free(filter->r);
free(filter->g);
free(filter->b);
free(filter);
}
Image *apply_filter(Image * const image, const Filter * const filter){
Image * const copy = copy_image(image);
for(int i = 0; i < image->height; ++i){
for(int j = 0; j < image->width; ++j){
int new_r = 0, new_g = 0, new_b = 0;
for(int u = 0; u < filter->height; ++u){
for(int v = 0; v < filter->width; ++v){
const int row = i + u - filter->height/2;
const int col = j + v - filter->width/2;
if(row >= 0 && row < image->height && col >= 0 && col < image->width){
new_r += *(copy->r + row * image->width + col) * *(filter->r + u * filter->width + v);
new_g += *(copy->g + row * image->width + col) * *(filter->g + u * filter->width + v);
new_b += *(copy->b + row * image->width + col) * *(filter->b + u * filter->width + v);
}
}
}
*(image->r + i * image->width + j) = _round(new_r);
*(image->g + i * image->width + j) = _round(new_g);
*(image->b + i * image->width + j) = _round(new_b);
}
}
delete_image(copy);
return image;
}
Image *apply_filter2(Image * const image, const Filter * const filter){
Filter * const raw = create_filter(image->width, image->height);
int low = 0, high = 255;
for(int i = 0; i < image->height; ++i){
for(int j = 0; j < image->width; ++j){
int new_r = 0, new_g = 0, new_b = 0;
for(int u = 0; u < filter->height; ++u){
for(int v = 0; v < filter->width; ++v){
const int row = i + u - filter->height/2;
const int col = j + v - filter->width/2;
if(row >= 0 && row < image->height && col >= 0 && col < image->width){
new_r += *(image->r + row * image->width + col) * *(filter->r + u * filter->width + v);
new_g += *(image->g + row * image->width + col) * *(filter->g + u * filter->width + v);
new_b += *(image->b + row * image->width + col) * *(filter->b + u * filter->width + v);
}
}
}
*(raw->r + i * raw->width + j) = new_r;
*(raw->g + i * raw->width + j) = new_g;
*(raw->b + i * raw->width + j) = new_b;
low = min(low, min(new_r, min(new_g, new_b)));
high = max(high, max(new_r, max(new_g, new_g)));
}
}
// printf("%d %d", low, high);
for(int i = 0; i < image->height; ++i){
for(int j = 0; j < image->width; ++j){
*(image->r + i * image->width + j) = _round((*(raw->r + i * raw->width + j) - low) / (float)(high - low) * 255);
*(image->g + i * image->width + j) = _round((*(raw->g + i * raw->width + j) - low) / (float)(high - low) * 255);
*(image->b + i * image->width + j) = _round((*(raw->b + i * raw->width + j) - low) / (float)(high - low) * 255);
}
}
delete_filter(raw);
return image;
}
/* Read an image from a given file pointer.
*/
Image *read_image(FILE * const fp){
char buf[BUFFER];
int width, height;
Image *res;
// Ignore 1st line.
fgets(buf, BUFFER, fp);
// Ignore comments.
fgets(buf, BUFFER, fp);
while(buf[0] == '#'){
fgets(buf, BUFFER, fp);
}
// Read width and height.
sscanf(buf, "%d %d", &width, &height);
fgets(buf, BUFFER, fp);
res = create_image(width, height);
for(int i = 0; i < width * height; ++i){
fread(res->r + i, 1, 1, fp);
fread(res->g + i, 1, 1, fp);
fread(res->b + i, 1, 1, fp);
}
return res;
}
void write_image(FILE * const fp, const Image * const image){
fprintf(fp, "P6\n");
fprintf(fp, "%d %d\n", image->width, image->height);
fprintf(fp, "255\n");
for(int i = 0; i < image->height * image->width; ++i){
fwrite(image->r + i, 1, 1, fp);
fwrite(image->g + i, 1, 1, fp);
fwrite(image->b + i, 1, 1, fp);
}
}
Image *gray(Image * const image){
for(int i = 0; i < image->height * image->width; ++i){
float n = *(image->r + i) * 0.298912 + *(image->g + i) * 0.586611 + *(image->b + i) * 0.114478;
*(image->r + i) = *(image->g + i) = *(image->b + i) = _round(n);
}
return image;
}
Image *sepia(Image * const image){
for(int i = 0; i < image->height * image->width; ++i){
*(image->r + i) = _round(*(image->r + i) / 255.0 * 240.0);
*(image->g + i) = _round(*(image->g + i) / 255.0 * 200.0);
*(image->b + i) = _round(*(image->b + i) / 255.0 * 145.0);
}
return image;
}
#ifndef _IMAGE_H_
#define _IMAGE_H_
#include <stdio.h>
#define WIDTH 640
#define HEIGHT 480
#define BUFFER 256
typedef unsigned char uchar;
typedef struct {
int width;
int height;
uchar *r;
uchar *g;
uchar *b;
} Image;
typedef struct {
int width;
int height;
float *r;
float *g;
float *b;
} Filter;
Image *create_image(const int width, const int height);
void delete_image(Image * const image);
Image *copy_image(const Image * const image);
Filter *create_filter(const int width, const int height);
void delete_filter(Filter * const filter);
Image *apply_filter(Image * const image, const Filter * const filter);
Image *apply_filter2(Image * const image, const Filter * const filter);
Image *read_image(FILE * const fp);
void write_image(FILE * const fp, const Image * const image);
Image *gray(Image * const image);
Image *sepia(Image * const image);
#endif
#include <stdio.h>
#include "image.h"
#include "filter.h"
int main(){
Image *image;
FILE *fin, *fout;
// Read an image.
fin = fopen("scene.ppm", "r");
if(fin == NULL){
printf("File not found.\n");
return 1;
}
image = read_image(fin);
fclose(fin);
// Do something.
sepia(image);
// Write an image.
fout = fopen("sepia.ppm", "wb");
write_image(fout, image);
delete_image(image);
fclose(fout);
return 0;
}
#include <stdio.h>
#include "image.h"
#include "filter.h"
int main(){
Image *image;
FILE *fin, *fout;
// Read an image.
fin = fopen("scene.ppm", "r");
if(fin == NULL){
printf("File not found.\n");
return 1;
}
image = read_image(fin);
fclose(fin);
// Do something.
sharp(image);
// Write an image.
fout = fopen("sharp.ppm", "wb");
write_image(fout, image);
delete_image(image);
fclose(fout);
return 0;
}
#include <stdio.h>
#include "image.h"
#include "filter.h"
int main(){
Image *image;
FILE *fin, *fout;
// Read an image.
fin = fopen("scene.ppm", "r");
if(fin == NULL){
printf("File not found.\n");
return 1;
}
image = read_image(fin);
fclose(fin);
// Do something.
sharp2(image);
// Write an image.
fout = fopen("sharp2.ppm", "wb");
write_image(fout, image);
delete_image(image);
fclose(fout);
return 0;
}
#include <stdio.h>
#include "image.h"
#include "filter.h"
int main(){
Image *image;
FILE *fin, *fout;
// Read an image.
fin = fopen("scene.ppm", "r");
if(fin == NULL){
printf("File not found.\n");
return 1;
}
image = read_image(fin);
fclose(fin);
// Do something.
uniform(image);
// Write an image.
fout = fopen("uniform.ppm", "wb");
write_image(fout, image);
delete_image(image);
fclose(fout);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment