#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
/* 画像の構造体 */
typedef struct{
int width;
int height;
float **r;
float **g;
float **b;
}ColorImage;
/* 1ワード読み込む関数 */
void getword(FILE *fp, char *word);
/* PPMフォーマットの画像を読み込む関数 */
void loadPPM(char* filename, ColorImage *ci);
/* 画像をPPMフォーマットで書き出す関数 */
void savePPM(char* filename, ColorImage *ci);
/* ネガポジ変換 */
void nega_posi(ColorImage *cimage);
/* コントラスト強調 */
void contrast(ColorImage *cimage);
/* ガンマ補正 */
void gamma_ps(ColorImage *cimage);
/* 量子化 */
void quantize(ColorImage *cimage);
/* クロマキー */
void chroma_key(ColorImage *fg, ColorImage *bg);
int main(void)
{
char *outputfile={"outputchroma.ppm"};
char *inputfile={"peppers.ppm"};
ColorImage cimage[2];
int pros=4;
/*0:ネガポジ、1:コントラスト強調、2:ガンマ補正、
3:量子化、4:クロマキー*/
if(pros==0){ //ネガポジ
loadPPM(inputfile, cimage);
nega_posi(cimage);
savePPM(outputfile, cimage);
}
else if(pros==1){
loadPPM(inputfile, cimage);
contrast(cimage);
savePPM(outputfile, cimage);
}
else if(pros==2){
loadPPM(inputfile, cimage);
gamma_ps(cimage);
savePPM(outputfile, cimage);
}
else if(pros==3){
loadPPM(inputfile, cimage);
quantize(cimage);
savePPM(outputfile, cimage);
}
//Chroma Key
else {
loadPPM("foreground.ppm", cimage);
loadPPM("background.ppm", &cimage[1]);
chroma_key(cimage, &cimage[1]);
savePPM(outputfile, cimage);
}
return 0;
}
void nega_posi(ColorImage *cimage)
{
/*y(i, j) = 255 − x(i, j)
に基づいてネガポジ変換する*/
int i,j;
for(i=0;i<cimage->width;i++){
for(j=0;j<cimage->height;j++){
cimage->r[i][j]=255-cimage->r[i][j];
cimage->g[i][j]=255-cimage->g[i][j];
cimage->b[i][j]=255-cimage->b[i][j];
}
}
}
void contrast(ColorImage *cimage)
{
int i,j;
for(i=0;i<cimage->width;i++){
for(j=0;j<cimage->height;j++){
cimage->r[i][j]=1.5*cimage->r[i][j]-10;
cimage->g[i][j]=1.5*cimage->g[i][j]-10;
cimage->b[i][j]=1.5*cimage->b[i][j]-10;
}
}
}
void gamma_ps(ColorImage *cimage)
{
int i,j;
for(i=0;i<cimage->width;i++){
for(j=0;j<cimage->height;j++){
cimage->r[i][j]=powf(cimage->r[i][j],1.4);
cimage->g[i][j]=powf(cimage->g[i][j],1.4);
cimage->b[i][j]=powf(cimage->b[i][j],1.4);
}
}
}
void quantize(ColorImage *cimage)
{
int i,j;
for(i=0;i<cimage->width;i++){
for(j=0;j<cimage->height;j++){
/*この場合は7ビットにビットシフトを用いて量子化する*/
cimage->r[i][j]=((int)cimage->r[i][j]>>(8-1))<<(8-1);
cimage->g[i][j]=((int)cimage->g[i][j]>>(8-1))<<(8-1);
cimage->b[i][j]=((int)cimage->b[i][j]>>(8-1))<<(8-1);
}
}
}
// insert forground image into background.
void chroma_key(ColorImage *fg, ColorImage *bg)
{
int i,j;
int α=12, β=80, γ=50;
for(i=0;i<fg->width;i++){
for(j=0;j<fg->height;j++){
if(fg->r[i][j]<=α && fg->g[i][j]>=β && fg->g[i][j]<=γ){
fg->r[i][j]=bg->r[i][j];
fg->g[i][j]=bg->g[i][j];
fg->b[i][j]=bg->b[i][j];
}
}
}
}
void savePPM(char* filename, ColorImage *ci)
{
/* save file in PGM P3 format */
int i, j;
FILE *out;
/* ファイルをオープン */
out=fopen(filename, "w");
/* ファイルが存在しなければエラー */
if (out==NULL){
printf("Cannot open file\n");
exit(0);
}
/* ファイルのヘッダ情報を書き出す */
fprintf(out, "P3\n%d %d\n255\n", ci->width, ci->height);
/* 画素値を書き出す */
/* 画素値を0~255に制限するプログラム */
for(i=0;i<ci->height;i++){
for(j=0;j<ci->width;j++){
if(ci->r[i][j]<0){
ci->r[i][j]=0;
}
if(ci->r[i][j]>=255){
ci->r[i][j]=255;
}
if(ci->g[i][j]<0){
ci->g[i][j]=0;
}
if(ci->g[i][j]>=255){
ci->g[i][j]=255;
}
if(ci->b[i][j]<0){
ci->b[i][j]=0;
}
if(ci->b[i][j]>=255){
ci->b[i][j]=255;
}
}
}
for(i=0;i<ci->height;i++){
for(j=0;j<ci->width;j++){
fprintf(out, "%d ", (int)ci->r[i][j]);
fprintf(out, "%d ", (int)ci->g[i][j]);
fprintf(out, "%d ", (int)ci->b[i][j]);
}
}
fclose(out);
}
void loadPPM(char* filename, ColorImage *ci)
{
char word[1000];
int i,j;
FILE *in;
in=fopen(filename, "rb");
if(in==NULL){
printf("Cannot open file\n");
exit(0);
}
getword(in, word);
getword(in, word);
sscanf(word,"%d",&(ci->width));
getword(in, word);
sscanf(word,"%d",&(ci->height));
getword(in, word);
ci->r=(float **)malloc(ci->height*sizeof(float *));
ci->g=(float **)malloc(ci->height*sizeof(float *));
ci->b=(float **)malloc(ci->height*sizeof(float *));
if(ci->r==NULL||ci->g==NULL||ci->b==NULL) {
printf("Error in malloc");
exit(0);
}
for(i=0;i<ci->height;i++){
ci->r[i]=(float *)malloc(ci->width*sizeof(float));
ci->g[i]=(float *)malloc(ci->width*sizeof(float));
ci->b[i]=(float *)malloc(ci->width*sizeof(float));
if(ci->r[i]==NULL||ci->g==NULL||ci->b==NULL) {
printf("Error in malloc");
exit(0);
}
}
/*discard one CR*/
fgetc(in);
for(i=0;i<ci->height;i++){
for(j=0;j<ci->width;j++){
int tmpr, tmpg, tmpb;
fscanf(in, "%s", word); sscanf(word,"%d",&(tmpr));
fscanf(in, "%s", word); sscanf(word,"%d",&(tmpg));
fscanf(in, "%s", word); sscanf(word,"%d",&(tmpb));
ci->r[i][j]=(float)tmpr;
ci->g[i][j]=(float)tmpg;
ci->b[i][j]=(float)tmpb;
}
}
fclose(in);
}
void getword(FILE *fp, char *word)
{
fscanf(fp, "%s", word);
/* while(word[0]=='#'){
fscanf(fp, "%s", word);
}*/
if(word[0]=='#'){
while(word[0]!=10){
word[0]=(int)fgetc(fp);
}
fscanf(fp, "%s", word);
}
}
Segmentation fault: 11の原因
Segmentation fault: 11の原因
以下のコードでforeground.ppmを前景画像,background.ppmを背景画像として 前景画像の各画素値において赤の値がα以下, かつ緑の値がβ以上, かつ青の値がγ以下の時, その画素を背景画像の同じ場所の画素に置き換え, その結果を画像output.ppmに出力したいのですが、Segmentation fault: 11とエラーが出ました。chroma_key関数を実行するときにエラーが出たのでそこが原因だとは思うのですが、原因がわからないので教えて欲しいです。
Re: Segmentation fault: 11の原因
全体をよく見てはいないのですが、おそらく
ではないかと
// insert forground image into background.
void chroma_key(ColorImage *fg, ColorImage *bg)
{
int i,j;
int α=12, β=80, γ=50;
//for(i=0;i<fg->width;i++){
for(i=0;i<fg->height;i++){
// for(j=0;j<fg->height;j++){
for(j=0;j<fg->width;j++){
if(fg->r[i][j]<=α && fg->g[i][j]>=β && fg->g[i][j]<=γ){
fg->r[i][j]=bg->r[i][j];
fg->g[i][j]=bg->g[i][j];
fg->b[i][j]=bg->b[i][j];
}
}
}
}
Re: Segmentation fault: 11の原因
ループ条件のwidthとheightが逆ですね。
他の関数にも同じ間違いが見られます。
他の関数にも同じ間違いが見られます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: Segmentation fault: 11の原因
指摘された点を書き直したら、実行できたのですがクロマキー合成されてない前景画像が表示されます。他に間違っている点はありますか?
Re: Segmentation fault: 11の原因
fg->g[i][j]<=γ
という条件がおかしいですね。
緑を2回比較してしまっています。
正しくは
fg->b[i][j]<=γ
でしょう。
という条件がおかしいですね。
緑を2回比較してしまっています。
正しくは
fg->b[i][j]<=γ
でしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)