10ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Ceres Solver - A fast non-linear least squares minimizer 20ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Copyright 2012 Google Inc. All rights reserved. 30ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// http://code.google.com/p/ceres-solver/ 40ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 50ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Redistribution and use in source and binary forms, with or without 60ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// modification, are permitted provided that the following conditions are met: 70ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 80ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions of source code must retain the above copyright notice, 90ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// this list of conditions and the following disclaimer. 100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions in binary form must reproduce the above copyright notice, 110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// this list of conditions and the following disclaimer in the documentation 120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// and/or other materials provided with the distribution. 130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Neither the name of Google Inc. nor the names of its contributors may be 140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// used to endorse or promote products derived from this software without 150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// specific prior written permission. 160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// POSSIBILITY OF SUCH DAMAGE. 280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Author: strandmark@google.com (Petter Strandmark) 300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Simple class for accessing PGM images. 320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#ifndef CERES_EXAMPLES_PGM_IMAGE_H_ 340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#define CERES_EXAMPLES_PGM_IMAGE_H_ 350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <algorithm> 370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <cstring> 380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <fstream> 390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <iostream> 400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <sstream> 410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <string> 420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <vector> 430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "glog/logging.h" 450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace ceres { 470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace examples { 480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongclass PGMImage { 510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong public: 520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Create an empty image 530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong PGMImage(int width, int height); 540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Load an image from file 550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong explicit PGMImage(std::string filename); 560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Sets an image to a constant 570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong void Set(double constant); 580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Reading dimensions 600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int width() const; 610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int height() const; 620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int NumPixels() const; 630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Get individual pixels 650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong Real* MutablePixel(int x, int y); 660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong Real Pixel(int x, int y) const; 670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong Real* MutablePixelFromLinearIndex(int index); 680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong Real PixelFromLinearIndex(int index) const; 690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int LinearIndex(int x, int y) const; 700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Adds an image to another 720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong void operator+=(const PGMImage& image); 730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Adds a constant to an image 740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong void operator+=(Real a); 750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Multiplies an image by a constant 760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong void operator*=(Real a); 770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // File access 790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong bool WriteToFile(std::string filename) const; 800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong bool ReadFromFile(std::string filename); 810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Accessing the image data directly 830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong bool SetData(const std::vector<Real>& new_data); 840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const std::vector<Real>& data() const; 850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong protected: 870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int height_, width_; 880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong std::vector<Real> data_; 890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}; 900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// --- IMPLEMENTATION 920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongPGMImage<Real>::PGMImage(int width, int height) 950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong : height_(height), width_(width), data_(width*height, 0.0) { 960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongPGMImage<Real>::PGMImage(std::string filename) { 1000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (!ReadFromFile(filename)) { 1010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong height_ = 0; 1020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong width_ = 0; 1030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvoid PGMImage<Real>::Set(double constant) { 1080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < data_.size(); ++i) { 1090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong data_[i] = constant; 1100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongint PGMImage<Real>::width() const { 1150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return width_; 1160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongint PGMImage<Real>::height() const { 1200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return height_; 1210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongint PGMImage<Real>::NumPixels() const { 1250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return width_ * height_; 1260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongReal* PGMImage<Real>::MutablePixel(int x, int y) { 1300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return MutablePixelFromLinearIndex(LinearIndex(x, y)); 1310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongReal PGMImage<Real>::Pixel(int x, int y) const { 1350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return PixelFromLinearIndex(LinearIndex(x, y)); 1360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongReal* PGMImage<Real>::MutablePixelFromLinearIndex(int index) { 1400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CHECK(index >= 0); 1410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CHECK(index < width_ * height_); 1420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CHECK(index < data_.size()); 1430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return &data_[index]; 1440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongReal PGMImage<Real>::PixelFromLinearIndex(int index) const { 1480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CHECK(index >= 0); 1490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CHECK(index < width_ * height_); 1500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CHECK(index < data_.size()); 1510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return data_[index]; 1520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongint PGMImage<Real>::LinearIndex(int x, int y) const { 1560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return x + width_*y; 1570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Adds an image to another 1600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvoid PGMImage<Real>::operator+= (const PGMImage<Real>& image) { 1620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CHECK(data_.size() == image.data_.size()); 1630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < data_.size(); ++i) { 1640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong data_[i] += image.data_[i]; 1650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Adds a constant to an image 1690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvoid PGMImage<Real>::operator+= (Real a) { 1710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < data_.size(); ++i) { 1720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong data_[i] += a; 1730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Multiplies an image by a constant 1770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvoid PGMImage<Real>::operator*= (Real a) { 1790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < data_.size(); ++i) { 1800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong data_[i] *= a; 1810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 1850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongbool PGMImage<Real>::WriteToFile(std::string filename) const { 1860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong std::ofstream outputfile(filename.c_str()); 1870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong outputfile << "P2" << std::endl; 1880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong outputfile << "# PGM format" << std::endl; 1890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong outputfile << " # <width> <height> <levels> " << std::endl; 1900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong outputfile << " # <data> ... " << std::endl; 1910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong outputfile << width_ << ' ' << height_ << " 255 " << std::endl; 1920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Write data 1940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int num_pixels = width_*height_; 1950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < num_pixels; ++i) { 1960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Convert to integer by rounding when writing file 1970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong outputfile << static_cast<int>(data_[i] + 0.5) << ' '; 1980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 20079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return bool(outputfile); // Returns true/false 2010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 2020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace { 2040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Helper function to read data from a text file, ignoring "#" comments. 2060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename T> 2070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongbool GetIgnoreComment(std::istream* in, T& t) { 2080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong std::string word; 2090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong bool ok; 2100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong do { 2110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ok = true; 2120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong (*in) >> word; 2130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (word.length() > 0 && word[0] == '#') { 2140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Comment; read the whole line 2150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ok = false; 2160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong std::getline(*in, word); 2170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } while (!ok); 2190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Convert the string 2210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong std::stringstream sin(word); 2220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong sin >> t; 2230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Check for success 2250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (!in || !sin) { 2260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 2270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return true; 2290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 2300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} // namespace 2310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 2330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongbool PGMImage<Real>::ReadFromFile(std::string filename) { 2340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong std::ifstream inputfile(filename.c_str()); 2350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // File must start with "P2" 2370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong char ch1, ch2; 2380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong inputfile >> ch1 >> ch2; 2390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (!inputfile || ch1 != 'P' || (ch2 != '2' && ch2 != '5')) { 2400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 2410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Read the image header 2440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int two_fifty_five; 2450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (!GetIgnoreComment(&inputfile, width_) || 2460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong !GetIgnoreComment(&inputfile, height_) || 2470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong !GetIgnoreComment(&inputfile, two_fifty_five) ) { 2480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 2490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Assert that the number of grey levels is 255. 2510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (two_fifty_five != 255) { 2520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 2530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Now read the data 2560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int num_pixels = width_*height_; 2570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong data_.resize(num_pixels); 2580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (ch2 == '2') { 2590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Ascii file 2600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < num_pixels; ++i) { 2610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int pixel_data; 2620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong bool res = GetIgnoreComment(&inputfile, pixel_data); 2630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (!res) { 2640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 2650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong data_[i] = pixel_data; 2670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // There cannot be anything else in the file (except comments). Try reading 2690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // another number and return failure if that succeeded. 2700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong int temp; 2710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong bool res = GetIgnoreComment(&inputfile, temp); 2720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (res) { 2730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 2740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } else { 2760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Read the line feed character 2770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (inputfile.get() != '\n') { 2780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 2790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Binary file 2810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // TODO(strandmark): Will not work on Windows (linebreak conversion). 2820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < num_pixels; ++i) { 2830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong unsigned char pixel_data = inputfile.get(); 2840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (!inputfile) { 2850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 2860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong data_[i] = pixel_data; 2880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // There cannot be anything else in the file. Try reading another byte 2900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // and return failure if that succeeded. 2910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong inputfile.get(); 2920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (inputfile) { 2930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 2940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return true; 2980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 2990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 3010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongbool PGMImage<Real>::SetData(const std::vector<Real>& new_data) { 3020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // This function cannot change the dimensions 3030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong if (new_data.size() != data_.size()) { 3040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return false; 3050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 3060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong std::copy(new_data.begin(), new_data.end(), data_.begin()); 3070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return true; 3080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 3090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate<typename Real> 3110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongconst std::vector<Real>& PGMImage<Real>::data() const { 3120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return data_; 3130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 3140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} // namespace examples 3160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} // namespace ceres 3170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#endif // CERES_EXAMPLES_PGM_IMAGE_H_ 320