チーム19C6
課題名
Filter Range
研究者名
Takahiro Niki
Sara Morita
概要
C言語を扱い、モザイクとぼかしを範囲指定して行った。
Cygwinを用いてプログラムを実行した。
15F3,16F2を参考にした。
ソースコード
mobo.c
#include <gd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(const int argc,const char *argv[]){
FILE *out,*in;
gdImagePtr im,im_new; int width,height,i,j,color,r,g,b,pixel,l,k,y,c,s,x1,x2,y1,y2;
int R[8],G[8],B[8];
if(argv[1]==NULL | | argv[2]==NULL | | !strcmp(argv[1],argv[2])){ printf("argument error\n"); exit(-1); }
if((in=fopen(argv[1],"r"))==NULL){ printf("file open error for %s\n",argv[1]); exit(-1); } //第二引数で指定されたファイルを書き出し用にオープン if((out=fopen(argv[2],"wb"))==NULL){ printf("file open error for %s\n",argv[2]); exit(-1); }
im = gdImageCreateFromJpeg(in);
width=gdImageSX(im); height=gdImageSY(im);
im_new= gdImageCreateTrueColor(width,height);
printf("choose mosaic or bokashi : ");
char choice[100]; scanf("%s",&choice);
if(strcmp(choice,"mosaic")==0){
// nはモザイクのピクセルの大きさ printf("pixel size\n"); scanf("%d", &s);
// 座標1はモザイクの左上の角 printf("coordinate1\n"); printf("x1:"); scanf("%d", &x1); printf("y1:"); scanf("%d", &y1);
// 座標1はモザイクの右下の角
printf("coordinate2\n"); printf("x2:"); scanf("%d", &x2); printf("y2:"); scanf("%d", &y2);
// 読み込んだ画像を新規画像にコピー for(i=0; i<width; i++){ for(j=0; j<height; j++){ pixel = gdImageGetPixel(im, i, j); r = gdImageRed(im, pixel); g = gdImageGreen(im, pixel); b = gdImageBlue(im, pixel); color = gdImageColorExact(im_new, r, g, b); gdImageSetPixel(im_new, i, j, color); } }
// モザイク処理 // 処理範囲は座標1と座標2を結んだ線分を対角線に持つ長方形内部 for(i=x1; i<x2-s; i=i+s){ for(j=y1; j<y2-s; j=j+s){ r=0; g=0; b=0;
for(k=0; k<s; k++){ for(l=0; l<s; l++){ pixel = gdImageGetPixel(im, i+k, j+l); r = r + gdImageRed(im, pixel); g = g + gdImageGreen(im, pixel); b = b + gdImageBlue(im, pixel); } }
// アベレージングフィルタ r = r / s / s; g = g / s / s; b = b / s / s;
// 画素のエラー処理 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;
// モザイク処理した画素の貼り付け for(k=0; k<s; k++){ for(l=0; l<s; l++){
// 画素の座標のエラー処理 if(j+k < height){ if(i+l < width){ color = gdImageColorExact(im_new, r, g, b); gdImageSetPixel(im_new, i+k, j+l, color); } } } } } }
}
else if(strcmp(choice,"bokashi")==0){
// nはぼかしのピクセルの大きさ printf("pixel size\n"); scanf("%d", &s);
// 座標1はぼかしの左上の角 printf("coordinate1\n"); printf("x1:"); scanf("%d", &x1); printf("y1:"); scanf("%d", &y1);
// 座標1はぼかしの右下の角
printf("coordinate2\n"); printf("x2:"); scanf("%d", &x2); printf("y2:"); scanf("%d", &y2);
// 読み込んだ画像を新規画像にコピー for(i=0; i<width; i++){ for(j=0; j<height; j++){ pixel = gdImageGetPixel(im, i, j); r = gdImageRed(im, pixel); g = gdImageGreen(im, pixel); b = gdImageBlue(im, pixel); color = gdImageColorExact(im_new, r, g, b); gdImageSetPixel(im_new, i, j, color); } }
// ぼかし処理 // 処理範囲は座標1と座標2を結んだ線分を対角線に持つ長方形内部 for(i=x1+(s/2); i<x2-(s/2); i++){ for(j=y1+(s/2); j<y2-(s/2); j++){ int sumr=0,sumg=0,sumb=0; int r=0,g=0,b=0;
for(k=-(s/2); k<=(s/2); k++){ for(l=-(s/2); l<=(s/2); l++){ pixel = gdImageGetPixel(im, i+k, j+l); sumr = sumr + gdImageRed(im, pixel); sumg = sumg + gdImageGreen(im, pixel); sumb = sumb + gdImageBlue(im, pixel); } } r = sumr/(s*s); b = sumb/(s*s); g = sumg/(s*s); color = gdImageColorExact(im_new, r, g, b); gdImageSetPixel(im_new, i+k, j+l, color); } } } else{ printf("error\n"); } gdImageJpeg(im_new,out,-1); fclose(in); fclose(out); return 0;
}
実行結果
Before | After | |
モザイク | 範囲(100,100)から(400,400) |
|
ぼかし | 範囲(150,150)から(300,300) |
考察
範囲指定は左上の角と右下の角を指定することでできた。
しかし指定した左上の値より右下の値の方が大きかった場合、エラーにするか値を入れ替える必要があったが今回は時間がなく考えられなかった。
また、高速フーリエ変換の画像処理を実装しようとしたができなかった。
- 最終更新:2019-07-15 16:23:43