File mapseams.c of Package arachne
/*
mapseams.c
Author: Hayden Walles
Date: 29 September 2007
A demonstration program that produces an image of the seam map of an input image.
*/
/*
Copyright (C) 2007, 2008 Hayden Walles
This file is part of Arachne.
Arachne is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Arachne is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include "image.h"
#include <seamstress.h>
void printUsage(void){
fprintf(stderr,"Usage: mapseams [-h] [-r] [-d D] infile [outfile]\nMap the minimal seams of an image. Takes an input image, computes all of its minimal seams and outputs an image of the same size as the input where each pixel's colour indicates where in the sequence of seam removals that pixel would be removed. The first seam is coloured black, the last white.\n\n");
fprintf(stderr," -r Use dynamic energy\n");
fprintf(stderr," -d x Compute the map for vertical (x is v) or horizontal (x is h) seam removals.\n");
fprintf(stderr," -h Print this help and exit.\n");
}
int saveMap(char *filename,SEAM_MAP *map,int width,int height,int *error){
IMAGE *image;
int l,h,span;
int i,j;
int lum,result;
*error=IMAGE_E_OK;
image=newImage(width,height,error);
if(image==NULL)
return 0;
l=h=getMap(map,0,0);
for(i=0;i<height;i++){
for(j=0;j<width;j++){
if(getMap(map,i,j)<l)
l=getMap(map,i,j);
if(getMap(map,i,j)>h)
h=getMap(map,i,j);
}
}
span=h-l;
for(i=0;i<height;i++){
for(j=0;j<width;j++){
lum=(getMap(map,i,j)-l)*255/span;
setPixel(image,i,j,lum,lum,lum);
}
}
result=saveImage(filename,image,error);
deleteImage(image);
return result;
}
int main(int argc, char **argv){
char *inname,*mapname="map.tif";
char scratchname[128];
int i,j;
int count;
IMAGE *in;
SEAM_UNPICKER *pic;
SEAM_MAP *map;
int error;
int dynenergy=0;
int direction=0;
setbuf(stdout,NULL);
count=0;
for(i=1;i<argc;i++){
if(argv[i][0]=='-'){
if(argv[i][1]=='r'){
dynenergy=1;
}
else if(argv[i][1]=='d'){
if(argv[i][2]=='v')
direction=0;
else if(argv[i][2]=='h')
direction=1;
else{
fprintf(stderr,"mapseams: Invalid direction.\n");
exit(1);
}
}
else if (argv[i][1]=='h'){
printUsage();
exit(0);
}
else {
fprintf(stderr,"mapseams: Unknown option %s\n",argv[i]);
exit(1);
}
}
else if(count==0){
inname=argv[i];
count++;
}
else if(count==1){
mapname=argv[i];
count++;
}
else {
fprintf(stderr,"Too many arguments\n");
exit(1);
}
}
if(count==0){
fprintf(stderr,"No input file specified!\n");
exit(1);
}
printf("Input image: %s\nMap image: %s\n",inname,mapname);
if(direction==0)
printf("Computing vertical seams.\n");
else
printf("Computing horizontal seams\n");
if(dynenergy)
printf("Using dynamic energy.\n");
printf("Loading image...");
if((in=loadImage(inname,&error))==NULL){
fprintf(stderr,"Error loading image\n");
exit(1);
}
printf("done\n");
if((pic=seamstressNewUnpicker(imageCols(in),imageRows(in),direction,0,dynenergy,&error))==NULL){
fprintf(stderr,"Out of memory\n");
exit(1);
}
for(i=0;i<imageRows(in);i++)
unpickerSetRowRGB32(pic,i,in->pixels+imageWidth(in)*i*4);
printf("Computing energy...");
unpickerComputeEnergy(pic,NULL,NULL,NULL,&error);
printf("done\n");
printf("Computing seam map:\n");
map=unpickerMap(pic,NULL,NULL,&error);
unpickerDelete(pic);
printf("done.\n");
printf("Saving map...");
saveMap(mapname,map,imageWidth(in),imageHeight(in),&error);
printf("done\n");
return 0;
}