001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2023 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit https://imagingbook.com for additional details. 008 ******************************************************************************/ 009 010package imagingbook.common.sift.scalespace; 011 012import static java.lang.Math.pow; 013import static java.lang.Math.sqrt; 014 015/** 016 * <p> 017 * Represents a single "octave" in a hierarchical Gaussian scale space. See Secs. 25.1.2 and 25.1.4 of [1] for more 018 * details. This class defines no public constructor. 019 * </p> 020 * <p> 021 * [1] W. Burger, M.J. Burge, <em>Digital Image Processing – An Algorithmic Introduction</em>, 3rd ed, Springer 022 * (2022). 023 * </p> 024 * 025 * @author WB 026 * @version 2022/11/20 027 */ 028public class GaussianOctave extends ScaleOctave<ScaleLevel> { 029 030 /** 031 * Constructor (non-public). 032 * @param p the index of the new octave 033 * @param Q the number of scale levels inside the new octave 034 * @param Gbot the bottom scale elevel to start with 035 * @param botIndex the bottom scale level index 036 * @param topIndex the top scale level index 037 * @param sigma_0 the scale at scale level with index 0 038 */ 039 GaussianOctave(int p, int Q, ScaleLevel Gbot, int botIndex, int topIndex, double sigma_0) { 040 // initialize generic octave structures (no scale levels yet): 041 super(p, Q, Gbot.getWidth(), Gbot.getHeight(), botIndex, topIndex, sigma_0); 042 043 // assign the bottom octave level: 044 double sigmaA_bot = getAbsoluteScale(p, botIndex); 045 this.setLevel(botIndex, Gbot); 046 Gbot.setAbsoluteScale(sigmaA_bot); 047 048 // create octave levels q = botIndex + 1,...,topIndex 049 for (int q = botIndex + 1; q <= topIndex; q++) { 050 double sigmaA = getAbsoluteScale(p, q); // absolute scale of level q 051 // relative scale from bottom level (q = -1): 052 double sigmaR = sigma_0 * sqrt(pow(2, 2.0 * q/Q) - pow(2, -2.0/Q)); 053 054 // duplicate the botton scale level with the new absolute scale: 055 ScaleLevel G_pq = new ScaleLevel(Gbot, sigmaA); 056 // filter the new scale level (destructively): 057 G_pq.filterGaussian(sigmaR); 058 // insert the new scale level into this scale octave 059 this.setLevel(q, G_pq); 060 } 061 } 062 063}