The present invention is related to transmission of data through a noisy channel and, in particular, to a context-modeling component and context-modeling method used in a universal denoiser for recovering clean data from noisy data resulting from passing the clean data through a noisy data channel.
Whenever information is electronically encoded as original, or clean, data, and then transferred from the data source to a data destination, noise may be introduced by the transfer process, resulting in alteration of the original, clean data and reception of the data by the data destination as noisy data. For example, when information is electronically encoded as a sequence of binary bits and sent through a communications network, such as a local Ethernet, to a destination node, there is a small probability that any given bit within the original, or clean, sequence of binary bits ends up being corrupted during transfer through the Ethernet, resulting in a “0” bit in the clean data being altered to a “1” bit in the noisy data received at the destination node, or a “1” bit in the clean data altered to a “0” bit in the noisy data received at the destination node. Although electronic communications media are classic examples of noisy channels, almost any type of data transfer or storage may result in data corruption, and therefore may be modeled as a noisy channel. For example, there is a small probability, associated with each bit of a block of binary data, that the bit will be altered when the block of data is stored and then retrieved from a hard disk, or even when the block of data is transferred from local cache memory to global random-access memory within a computer system. In general, redundant data, including check sums and cyclical redundancy codes, are embedded into data encodings to allow corrupted data to be detected and repaired. However, the amount of redundant data needed, and the accompanying costs and inefficiencies associated with redundant data, grows as the acceptable level of undetectable and/or unrepairable data corruption decreases.
In many cases, data corruption may occur prior to a point in a process at which redundant information can be embedded into a data signal to facilitate error detection and correction. As one example, a scanner that optically scans a printed document to produce a digital, electronic encoding of an image of the document can be viewed as a noisy channel in which discrepancies between the digitally encoded image of the document and the original document may arise. Such discrepancies may be introduced by a variety of optical and electronic components within the scanner that focus an optical image of the document onto a light-detecting component that transforms the detected optical image into an electronically encoded image of the document. When the digitally encoded image of the document is displayed or printed, different types of noise may be perceived as graininess, irregularities along the edges of text characters or objects within graphical images, uneven shading or coloration, random speckling, or other such visually distinguishable differences between the printed or displayed version of the digitally encoded data and the original document.
Denoising techniques can be applied to a noisy, digitally encoded image in order to produce a denoised, digitally encoded image that more accurately represents the original document that was scanned to produce the noisy, digitally encoded image. Denoising techniques may also be applied to data received over channels that are too noisy for recovery of the original data using the redundant data incorporated within the data to facilitate error correction. A wide variety of additional applications of denoising techniques have been identified and are well known. Recently, a discrete universal denoiser method (“DUDE”) has been developed for denoising the noisy output signal of a discrete, memoryless data-transmission channel without relying on knowledge of, or assumptions concerning, the statistical properties of the original, or clean, signal input to the discrete, memory-less channel. Even more recently, the DUDE method has been extended for denoising continuous tone images, such as scanned documents or images. The extended DUDE method is referred to as the “DUDE-CTI method,” or simply as the “DUDE-CTI.” The DUDE-CTI method is intended for use in a variety of image and data scanning, processing, and transfer applications. The DUDE-CTI method has shown promising results for certain types of noisy channels. An efficient DUDE-CTI depends on collections of symbol-occurrence statistics for each of a large number of different pixel contexts observed within an image. Because of the large number of possible contexts, an expedient approach is to coalesce individual contexts into groups, or classes, of contexts, and to then collect statistics on a context-class basis, rather than for individual contexts. However, such methods depend on efficient and effective assignment of contexts to context classes. Information-theory researchers, denoising-method developers, and manufacturers and users of a variety of data acquisition, storage, processing, and transfer devices that employ denoisers, continue to seek efficient and effective context-modeling methods and context-modeling components for generating context classes and symbol-prediction classes, assigning contexts to context classes and symbol-prediction classes, gathering statistics related to symbol occurrence within context-classes and symbol-prediction errors related to symbol-prediction-classes, and for noisy-symbol prediction.
In various embodiments of the present invention, a context-based denoiser is applied to each noisy-image symbol embedded within a context to determine a replacement symbol for the noisy-signal symbol. The context-based denoiser includes a context-modeling component that efficiently generates context classes and symbol-prediction classes, assigns individual contexts to context classes and symbol-prediction classes, collects symbol-occurrence statistics related to the generated context classes and symbol-prediction classes, and, optionally, generates noisy-symbol predictions.
The present invention concerns methods and systems for denoising noisy signals received through noisy channels without information regarding the originally transmitted, clean signal. Methods and systems of the present invention are particularly well suited for denoising images corrupted by noise that can be modeled as a number of independent and identically distributed Gaussian random variables, or by various other types of random variables distributed according to other types of statistical distributions. The denoising methods and systems of the present invention are discussed below with reference to a document-scanning application, but these methods and systems are widely applicable to a variety of denoising applications, including denoising of transmitted, stored, and processed images, as well as denoising of general signals each comprising an ordered sequence of symbols selected from a finite symbol alphabet. In a first section, below, a general description of denoising is provided. In a following section, embodiments of the present invention are discussed in detail.
In various embodiments of the present invention, each symbol of a noisy signal, received through a noisy channel, is considered within a well-defined context of neighboring symbols. A noisy signal can be analyzed in a first pass to assign each symbol to a context class and to collect prediction-error statistics for context classes that allow, in a subsequent pass, likely clean-signal symbols corresponding to each noisy-signal symbol to be predicted.
A printed document that is to be scanned by a scanning device can be considered as a clean signal. In other words, the printed document can be viewed as a large set of pixel-intensity values that, when displayed or printed, would appear visually indistinguishable from the original, printed document. The pixel data actually obtained as a result of scanning may be considered to be a noisy signal.
A discrete universal denoiser for continuous-tone images (“DUDE-CTI”) has been developed for general denoising of digitally encoded images, and other noisy data. The DUDE-CTI method is next described, both to establish a conceptual framework for the following description of the present invention, as well as to contrast the approach represented by the DUDE-CTI to the methods and denoisers of the present invention.
In both the DUDE-CTI and the context-based denoisers of the present invention, an image signal, or digitally encoded image, is considered to be a two-dimensionally-ordered sequence of symbols, each symbol mapped to one of a finite set of numerical values. Most of the symbols in a signal have well-defined two-dimensional contexts, or neighborhoods, and these contexts play a significant role in both the DUDE-CTI and the denoisers of the present invention.
Many different context shapes and sizes are possible.
Images are generally 2-dimensional data sets, and analysis and denoising methods for images therefore frequently use 2-dimensional contexts symmetrically disposed with respect to the central symbol. In other types of data sets, other types of contexts may be appropriate. For example, in digitally encoded text files, comprising essentially a one-dimensional series of symbols, a single length of symbols that include the central symbol may be employed as a context. Other types of signals may profitably employ more complex, non-contiguous or higher-dimensional contexts.
The DUDE-CTI method employs a central-symbol predictor function {circumflex over (z)}( ).
The DUDE-CTI method computes an error ei for each symbol zi in the noisy signal as the difference between the observed symbol zi and the symbol predicted by the predictor function {circumflex over (z)}( ) for the context Ci for the symbol zi.
In a first pass of the DUDE-CTI denoiser, each symbol in a noisy image signal 808 is considered, and the error for each considered symbol is tabulated in the appropriate vector qCT for that symbol. For example, in
Unfortunately, when contexts of even modest size are used, a typical image will not contain a sufficient number of occurrences of each context to collect reliable, well-formed histograms of error occurrences, such as the histogram shown in
Context clustering can be thought of as a many-to-one mapping, or binning, of context vectors in a context-vector space into a set of context-cluster indices.
Next, the DUDE-CTI denoiser generates a function g(C, z) that computes a replacement symbol {circumflex over (x)} for a given central symbol z that occurs within context C observed in the noisy image signal. The replacement function g( ) can then be used in a second, symbol-by-symbol pass, to replace each symbol in the noisy image signal with a corresponding replacement symbol. The symbol replacement for each symbol in the noisy image signal is carried out independently. In other words, the contexts applied to the replacement function g( ) are the contexts observed in the noisy image signal, rather than partially symbol-replaced contexts. It should be noted that, in many cases, the replacement symbol x is identical to the corresponding observed symbol z in the noisy image signal.
Computation of the replacement function g( ) involves use of two matrices: (1) a matrix Π that represents a channel-noise model for the noise-inducing channel that generates symbol differences between the initial, clean image signal and the noisy image signal; and (2) a distortion matrix Λ that represents the distortions in a recovered image produced by substituting for symbol ai in the corresponding clean image signal any of the symbols a1, a2, . . . an, in alphabet A.
mcleanΠ={circumflex over (m)}noisy
{circumflex over (m)}noisy[i]=mclean[1]p(a1→ai)+mclean[2]p(a2→ai)+ . . . +mclean[n]p(an→ai)
The derived vector {circumflex over (m)}noisy 1404 is expected to be fairly close, relative to the signal size, to the vector mnoisy containing counts of symbols observed in a noisy signal. Provided that the channel-noise-model matrix Π is invertible, or an approximate or pseudo inverse of the matrix Π can be obtained by any of a number of matrix inversion methods, an observed vector mnoisy including the counts of occurrences of symbols observed in a noisy signal can be multiplied by the inverse of the channel-noise-model matrix Π to produce approximate estimates of the probabilities of occurrences of symbols in the clean signal:
mclean≈mnoisyΠ−1
This approximation technique can be extended to vectors {tilde over (q)}C
{tilde over (q)}clean,C
Thus, the symbol-replacement function g( ) produces a replacement character x for an observed central symbol z within a context C observed in the noisy signal.
In the previous section, a general background for context-based denoising of continuous-tone images is provided. In the current section, context-based denoising is again described, at a more abstract level, with introduction of notation conventions subsequently used in descriptions of various embodiments of the present invention. Then, context-modeling methods and a context-modeling component that represent embodiments of the present invention are discussed in overview, with reference to control-flow diagrams, and, finally, in greater detail with reference to a pseudocode implementation.
As discussed in the first section, specific prediction error-occurrence probability distributions qγ
{tilde over (q)}clean,C
As discussed in the previous section, a distortion vector dk→j can be produced by:
dk→j=Λi,j□Πi,k
Each element of the distortion vector includes a numerical estimate of the relative distortion produced when symbol ak in a noisy signal is replaced by the symbol aj when the corresponding symbol in the clean image is ai. An estimate of the distortion produced by replacing symbol ak, in a noisy signal within a context belonging to context class γi, by the replacement symbol aj, {circumflex over (d)}a
{circumflex over (d)}a
The derived quantities then allow for computation of a symbol-replacement function G(γi,zi) that generates a replacement symbol {circumflex over (x)} for noisy-image symbol zi occurring within a context belonging to context class γi within a noisy image:
|C|=|A|K
Referring again to
ei=zi−{circumflex over (z)}i
Consider random variables Z, {circumflex over (Z)}, and E to be random variables that model zi, {circumflex over (z)}i, and ei, respectively, and consider γ to be a random vector that models the possible values of the context classes γi. In the previously described denoiser, the denoiser function for a current sample is defined in terms of the empirical distribution of the input alphabet conditioned on the current context class γi. The prediction error distribution for the current context class γi and the current noisy-symbol prediction {circumflex over (z)}i
PE(E=zi−{circumflex over (z)}i|γ=γi,{circumflex over (Z)}={circumflex over (z)}i)
can be assumed to be a centered version of the original noisy distribution when conditioned on the prediction of value
PZ(Z=zi|γ=γi,{circumflex over (Z)}={circumflex over (z)}i)
or, symbolically:
PZ(Z=zi|γ=γi, {circumflex over (Z)}={circumflex over (z)}i)=PE(E=zi−{circumflex over (z)}i|γ=γi,{circumflex over (Z)}={circumflex over (z)}i)
Assuming that the prediction error distributions are independent of the actual predicted value {circumflex over (z)}i,
PE(E=ei|γ=γi,{circumflex over (Z)}={circumflex over (z)}i)=PE(E=ei|γ=γi)
all the statistics of class γ can be gathered in one symbol-prediction-error-occurrence vector. With this assumption, and with the assumption that the prediction error distribution of the current context class is a centered version of the original noisy distribution when conditioned on the prediction value, the estimated noisy conditional distribution for the current sample zi is:
PZ(Z=zi|γ=γi)=PE(E=ei|γ=γi)
Embodiments of the present invention are directed to various context modelers, as discussed with reference to
The signed wing gradients are combined, as shown in the following three equations, to produce an activity level (“AL”) that represents another numerical component of context-class and prediction-class assignment:
dH=|dE|+|dW|
dV=|dN|+|dS|
AL=dH+dV
A final computed component for context-class and prediction-class assignment is a computed metric φ, referred to as “the gradient direction,” although the computed metric φ is not strictly a gradient, according to the well-understood meaning of the term “gradient.” The gradient direction, or gradient angle, is computed as follows:
with φ is defined to be 90, or
when dH is 0. Other mappings of the ratio
can also used, in alternative embodiments, and, in yet additional embodiments, the metric φ may be computed from various alternative combinations of the computed values dN, dS, dE, and dW.
The wing gradients, activity level, and gradient angle are all reflective of changes in symbol values that occur over the context. The wing gradients are reflective of the horizontal and vertical symbol-value gradients within the context, and the activity level is reflective of the overall degree of variation of symbol values within the context. The gradient angle φ is reflective of the relative values of the dN and dS wing gradients. By contrast, the texture bitmap is more reflective of the detailed symbol-value variance within the context, and includes spatial, rather than merely directional, information.
{circumflex over (z)}corrected={circumflex over (z)}+biaspi
There are a number of different ways to compute a predicted noisy symbol {circumflex over (z)} for a given noisy symbol z that are employed in various embodiments of the present invention. Many of these techniques employ weighted wing gradients, with the weights for wing gradients dN, dS, dE, and dW computed as follows:
In a first technique, a minimum gradient is computed as follows:
dm=min(|dN|,|dE|,|dS|,|dW|)
Next, a threshold θ is computed as follows:
θ=grad_thresh×3×|A|
where grad_thresh is a parameter with a value greater than or equal to 0 and less than or equal to 1. For the K=20 context, described above, the integer “3” in the above equation is replaced with “5.” Next, final weights are computed by comparing the absolute value of each wing gradient to the computed minimum wing gradient, as:
Then, wing averages are computed as:
aN=(Cn+Cnn+(Cne+Cne)/2)/3
aE=(Ce+Cee+(Cne+Cse)/2)/3
aS=(Cs+Css+(Csw+Cse)/2)/3
aW=(Cw+Cww+(Cnw+Csw)/2)3
Finally, the predicted noisy symbol {circumflex over (z)} is computed as:
In a second version of noisy-symbol prediction, the wing-gradient weights take on only one of the two possible binary values “0” and “1.” The prediction is then computed using only those wing gradients with weight 1. First, a wing-gradient sign is computed for each wing, as follows:
When the wing-gradient sign is equal to 0, the corresponding wing-gradient is considered to be flat. Otherwise, the corresponding wing gradient is considered to be non-flat. If any of the wing gradients is flat, then the second predictor technique works in flat mode. In this mode, all elements of the context included exclusively in flat wings, or wings with wing-gradient sign values of 0, are used to compute the predicted noisy symbol, as follows:
When none of the wings are classified as flat, the second prediction technique switches to a non-flat mode. In this mode, if the predictor determines that the context lies along a ridge, such as the context shown in
In a third prediction technique, weights for the context elements are computed based on the relative position, expressed as a vertical-position/horizontal-position coordinate pair, from the central position of the context, as follows:
where wN, wS, wE, and wW are computed as described above. The coordinates indicate, in units of elements or symbols, the distance of a context element from the central symbol embedded within the context, with sign convention such that element ne has coordinates (−1, 1) and element ee has coordinate (−2, 0). Then, all of the elements of the context, multiplied by their respective weights, are averaged to produce the predicted noisy symbol {circumflex over (z)}.
In a C++-like pseudocode implementation, discussed below, the first prediction technique is implemented. However, in various embodiments of the present invention, the second and third techniques are used separately, or in conjunction with the first technique, depending on characteristics of the noisy image and characteristics of subsequent denoising components that employ the predicted noisy-image map {circumflex over (z)} produced by the context-modeling component. Additional noisy-symbol prediction techniques can be employed in alternative embodiments.
Next, a relatively simple, C++-like pseudocode implementation of one embodiment of the context-modeling component of a denoiser that represents one embodiment of the present invention is provided. The C++-like pseudocode implementation follows the above-described flow diagrams reasonably closely, and the following discussion will focus mostly on the higher-level concepts embodied in the pseudocode.
First, a large number of constants and type declarations are provided:
A first set of constants, on lines 1-7, are related to the dimensions of the noisy image zmxn, with the dimensions of the prefiltered image ymxn, binary mask umxn, metamap γmxn, and predicted noisy image {circumflex over (z)}mxn considered to be the same as those of the noisy image zmxn. In the pseudocode implementation, the first and last two rows and first and last two columns of the noisy map are not considered, as reflected in the constants declared on lines 4-7, since full contexts are not available for those rows and columns. In alternative embodiments, partial context can be defined for border regions. The constants on lines 8-9 define a symbol type, and also define the allowed symbols of alphabet A to range from 0-31. In other words, for the particular example addressed by the pseudocode implementation, the image contains 5-bit symbols. The constants defined on lines 10-27 define the maximum values for various numerical components of prediction-class and context-class descriptors, as well as the number of bits allocated for each of the numerical components within the prediction-class and context-class descriptors and the number of bins desired for the quantization functions for the numerical components. The parameter “grad_thresh,” discussed above, is defined on line 28. The maximum value of a prediction-class descriptor is defined on line 29, and types are defined for gradients, activity levels, bit texture maps, and gradient angles on lines 30-33.
Next, the class “classRelatedData” is declared:
Instances of the class “classRelatedData” together form an internal data map for storing computed numerical components of context-class and symbol-prediction-class descriptors. Each instance of the class “classRelatedData” stores wing gradients, an activity level, a textured bit map, and a gradient angle.
Next, the template class “map” is declared:
The template “class” is instantiated as five different maps corresponding to the prefiltered image ymxn, the binary mask umxn, the noisy image zmxn, the metamap γmxn, and the predicted noisy image {circumflex over (z)}mxn. The template class “map” includes functions for extracting and inputting map elements into the map, as well as functions for extracting elements of the K=12 context surrounding a current map element.
Next, a number of constants are defined related to the class “metaMapElement,” a declaration for which follows:
The class “metaMapElement” defines the elements for the metamap γmxn. This class includes function members that allow each of the numerical components of prediction-class and context-class descriptors to be extracted and to be inserted.
Next, type definitions for each of the different maps used in the current implementation of a modeling component that represents an embodiment of the present invention are defined:
The map type “computerData” is an internal map used in the implementation of the context-modeling component for storing the computed numerical components, prior to their quantization and truncation.
Finally, a class declaration for the context-modeling component is provided:
The class “modeler” includes pointers to the various maps, declared on lines 4-9, histograms for accumulating the number of occurrences of the various numerical components, on lines 11-16, quantization-bin arrays implementing quantization functions, declared on lines 18-23, the two arrays for accumulating statistics on prediction biases, declared on lines 28-29, and various local variables employed by private function members, declared on lines 25-26 and on lines 31-32. The class “modeler” includes an initialization function member “init,” declared on line 34, that initializes the histograms, quantization-bin arrays, and local variables. The class “modeler” additionally includes the following private function members: (1) “bin,” declared on line 36, which computes the quantization-bin-array values based on a histogram; (2) “compute data,” declared on line 37, which computes the numerical components of the prediction-class and context-class descriptors, including the extra bitmaps; (3) “predict,” declared on line 38, which implements the first of the three described prediction techniques for predicting the noisy symbol {circumflex over (z)} for a corresponding noisy-image symbol z; (4) “text,” declared on line 39, which computes the texture bitmap for a particular symbol; (5) “computeQ,” declared on line 40, which computes the quantization functions for the numerical components that are quantized; (6) “Q,” declared on line 41, which implements the quantization function for transforming numerical component values into quantized numerical component values; and (7) “pass1,” “pass2,” and “pass3,” declared on lines 43-45, that implement the first, second, and third passes discussed with reference to
Next, implementations of two function members of the template class “map” are provided, without further annotation:
Next, an implementation for the function member “computeData” of the class “modeler” is provided:
The function member “computeData” computes the signed wing gradients for currently considered prefiltered-map symbol, on lines 9-16, transforms these into unsigned equivalents on lines 18-32, inserts them into an internal-map element on lines 34-37, computes the absolute values of the wing gradients on lines 39-46, computes the activity level and inserts the activity level into the internal-map element on lines 48-51, computes the gradient angle and inserts the computed gradient angle into the internal-map element on lines 53-57, and updates the corresponding histograms on lines 59-64.
Next, an implementation of the function member “predict” for the class “modeler” is provided:
The function member “predict” carries out the above-described first prediction technique involving computing wing-gradient weights, the parameter θ, and a final predicted noisy symbol {circumflex over (z)}.
Next, an implementation of the private function member “text” of the class “modeler” is provided:
The function member “text” computes a texture bitmap for a currently considered noisy symbol.
Next, an implementation for the private function member “bin” for the class “modeler” is provided:
The routine “bin” carries out the binning process discussed above with reference to
Next, an implementation of the private function member “computeQ” of the class “modeler” is provided:
This function member computes the quantization functions for each of the quantized numerical components with prediction-class and context-class descriptors.
Next, an implementation of the function member “pass1” of the class “modeler” is provided:
In the for-loop of lines 5-11, each element in the prefiltered map is considered, and for each currently considered element, the numerical components activity level, gradient angle, and wing gradients are computed on line 8, the noisy symbol {circumflex over (z)} is predicted on line 9, and the texture bitmaps are computed on line 10. On line 12, the quantization functions are computed.
Next, an implementation of the private function member “Q” for the class “modeler” is provided:
This private function member essentially implements the quantization functions for all of the quantized numerical components.
Next, an implementation of the private function member “pass2” of the class “modeler” is provided:
This function member again traverses the prefiltered map, considering each symbol of the prefiltered map in the do-while-loop of lines 12-53. For each considered prefiltered-map symbol, the quantized and/or truncated numerical components of the prediction-class and context-class descriptors are computed on lines 16-43, and the numerical components are combined and entered into an element of the metamap on line 45. On lines 47-52, the bias-adjustment statistics of the current symbol are updated in the case that the current symbol has not been identified as noise degraded in the binary mask umxn.
Next, an implementation of the private function member “pass3” of the class “modeler” is provided:
In the for-loop of lines 7-11, the bias for each symbol-prediction class is computed, as discussed with reference to
Finally, implementations of the public function members “initialize” and “generateMetaMap” of the class “modeler” are provided:
Although the present invention has been described in terms of a particular embodiment, it is not intended that the invention be limited to this embodiment. Modifications within the spirit of the invention will be apparent to those skilled in the art. For example, an essentially limitless number of different implementations of the context-modeling component according to the present invention can be obtained by varying the data structures, control structures, modular organization, programming language, and various other programming characteristics of the implementation. A modeler component may be implemented in software, or in a combination of software and firmware, or even a combination of firmware and hardware circuitry, for use in various types of environments. Although, in the above discussion, two different types of contexts, a K=12 and a K=20 context, are discussed, any of a wide variety of different, alternative contexts may be employed, with corresponding adjustment of wing-gradient and texture bitmap calculations, as well as assessment of the various different types of noisy-symbol prediction techniques employ the different types of contexts. Although, in the above-discussed implementation, the numerical gradients activity level, gradient angle, wing gradients, and texture bitmap were employed to generate prediction-class and context-class descriptors, certain embodiments may use different numerical components, or certain of the above-described numerical components along with additional numerical components. Different noisy-symbol-prediction techniques from those described may be employed in alternative embodiments.
The foregoing description, for purposes of explanation, used specific nomenclature to provide a thorough understanding of the invention. However, it will be apparent to one skilled in the art that the specific details are not required in order to practice the invention. The foregoing descriptions of specific embodiments of the present invention are presented for purpose of illustration and description. They are not intended to be exhaustive or to limit the invention to the precise forms disclosed. Obviously many modifications and variations are possible in view of the above teachings. The embodiments are shown and described in order to best explain the principles of the invention and its practical applications, to thereby enable others skilled in the art to best utilize the invention and various embodiments with various modifications as are suited to the particular use contemplated. It is intended that the scope of the invention be defined by the following claims and their equivalents:
Number | Name | Date | Kind |
---|---|---|---|
5835034 | Seroussi et al. | Nov 1998 | A |
6021227 | Sapiro et al. | Feb 2000 | A |
7120308 | Guleryuz | Oct 2006 | B2 |
20050289406 | Weissman et al. | Dec 2005 | A1 |
20060047501 | Seroussi et al. | Mar 2006 | A1 |
Number | Date | Country | |
---|---|---|---|
20080247659 A1 | Oct 2008 | US |