<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 <h1 align="center">Scientific Programming in Python</h1>
<h2 align="center">Topic 6
Step4:  Local Binary Pattern Representation
Local Binary Pattern (LBP) is a simple yet very efficient texture operator which labels the pixels of an image by thresholding the neighborhood of each pixel and considers the result as a binary number. 
Due to its discriminative power and computational simplicity, LBP texture operator has become a popular approach in various applications. 
Perhaps the most important property of the LBP operator in real-world applications is its robustness to monotonic gray-scale changes caused, for example, by illumination variations. Another important property is its computational simplicity, which makes it possible to analyze images in challenging real-time settings.
Example of how LBP works
Step5:  Just an example of usage
<ASSISTANT_TASK:>
Python Code:
import numba
import numexpr as ne
import numpy as np
import matplotlib.pyplot as roberplot
import matplotlib.image as mpimg
%load_ext line_profiler
%load_ext memory_profiler
def rgb2gray(rgb):
    return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
def image_plot(img):
    roberplot.figure(figsize=(10,5))
    roberplot.imshow(img, cmap='gray')
    roberplot.axis('off')
    roberplot.show()
    
def histogram_plot(h):
    roberplot.figure(figsize=(5,10))
    roberplot.plot(range(len(h)), h)
    roberplot.xlim([-5,260])
    roberplot.ylim([0,200000])
    roberplot.xlabel('Feature index')
    roberplot.ylabel('Number of repetitions')
    roberplot.grid()
    roberplot.show()
Explanation: <h1 align="center">Scientific Programming in Python</h1>
<h2 align="center">Topic 6: Python Profiling and Optimization  </h2>
Notebook created by Martín Villanueva - martin.villanueva@usm.cl - DI UTFSM - May 2017.
End of explanation
def lbp(region):
    
    Region is a 3x3 ndarray
    
    ret = (region > region[1,1]).astype(int)
    return (2**7)*ret[0,0] + (2**6)*ret[0,1] + (2**5)*ret[0,2] + (2**4)*ret[1,2] + (2**3)*ret[2,2] + \
           (2**2)*ret[2,1] + (2**1)*ret[2,0] + (2**0)*ret[1,0]
def lbp_representation(image):
    
    Compute lbp representation of image
    
    m,n = image.shape
    ret = np.empty((m-2,n-2))
    for i in range(1,m-1):
        for j in range(1,n-1):
            ret[i-1,j-1] = lbp(image[i-1:i+2, j-1:j+2])
    return ret
def lbp_histogram(image):
    
    Compute lbp histogram representation of image
    
    lbp_image = lbp_representation(image)
    m,n = lbp_image.shape
    hist = np.zeros(256)
    for i in range(m):
        for j in range(n):
            hist[lbp_image[i,j]] += 1
    return hist 
Explanation: Local Binary Pattern Representation
Local Binary Pattern (LBP) is a simple yet very efficient texture operator which labels the pixels of an image by thresholding the neighborhood of each pixel and considers the result as a binary number. 
Due to its discriminative power and computational simplicity, LBP texture operator has become a popular approach in various applications. 
Perhaps the most important property of the LBP operator in real-world applications is its robustness to monotonic gray-scale changes caused, for example, by illumination variations. Another important property is its computational simplicity, which makes it possible to analyze images in challenging real-time settings.
Example of how LBP works:
Type of features LBP compute:
Then, each pixel in the image is encoded as a 8-bit binary number (or its corresponding decimal representation) which represents a unique feature. With this representation we can make a histogram of the distribution of such features!
End of explanation
img = mpimg.imread('data/doge.jpg')
img = rgb2gray(img)
image_plot(img)
lbp_image = lbp_representation(img)
image_plot(lbp_image)
h = lbp_histogram(img)
histogram_plot(h)
Explanation: Just an example of usage
End of explanation
<END_TASK>