How to find correlation between two images - python

I need to find correlation between two images, using numpy, but basic math only. I have the problem:"*
IndexError: index 5434 is out of bounds for axis 0 with size 5434*". And i have a code. Tell me what to do, pls.
img = PIL.Image.open("SR1.png").convert("L")
im = numpy.array(img)
img2 = PIL.Image.open("SR61.png").convert("L")
im2 = numpy.array(img2)
np.array(im,dtype=float)
np.array(im2,dtype=float)
import math
import cmath
def correlationCoefficient(X, Y, n) :
sum_X = 0
sum_Y = 0
sum_XY = 0
squareSum_X = 0
squareSum_Y = 0
i = 0
for i in range(n) :
sum_X = sum_X + X[i]
sum_Y = sum_Y + Y[i]
sum_XY = sum_XY + X[i] * Y[i]
squareSum_X = squareSum_X + X[i] * X[i]
squareSum_Y = squareSum_Y + Y[i] * Y[i]
i = i + 1
corr = (n * sum_XY - sum_X * sum_Y)/(cmath.sqrt((n * squareSum_X - sum_X * sum_X)* (n * squareSum_Y - sum_Y * sum_Y)))
return corr
X = im.flatten()
Y = im2.flatten()
n = len(X)
print ('{0:.6f}'.format(correlationCoefficient(X, Y, n)))

Here's a vectorized version of your function:
import numpy as np
def correlationCoefficient(X, Y):
n = X.size
sum_X = X.sum()
sum_Y = Y.sum()
sum_XY = (X*Y).sum()
squareSum_X = (X*X).sum()
squareSum_Y = (Y*Y).sum()
corr = (n * sum_XY - sum_X * sum_Y)/(np.sqrt((n * squareSum_X - sum_X * sum_X)* (n * squareSum_Y - sum_Y * sum_Y)))
return corr
It is also important to normalize your image arrays to avoid overflow:
from PIL import Image
img1 = Image.open("1.jpg").convert("L")
im1 = np.array(img1)/255
img2 = Image.open("2.jpg").convert("L")
im2 = np.array(img2)/255
print ('{0:.6f}'.format(correlationCoefficient(im1, im2)))

You can use the function corrcoef in numpy to find Peason correlation. First you need to flatten both image arrays:
np.corrcoef(im1.flatten(), im2.flatten())

Related

Speeding up custom adaptive smoothen filter with opencv in Python

I am new in Image Processing and trying to implement a custom filter I found in bibliography. I need to implement this in Python with opencv, but my implementation, though correct, is running really slowly. The algorithm can be described as follows:
Calculate normalized chromatic distances in a 3x3 neighborhood around a centre point
d_i = (|R_centre-R_i|+|G_centre-G_i|+|B_centre-B_i|)/(3x255) where centre point is the current pixel that iterates through whole picture, and i are the 8 points around it
Having calculated values d_0 through d_7 we calculate an array of 8 elements called c_i = (1-d_i)^10 which will be the values used in our convolution box
Our final convolution mask will be (1/sum(c))*([c_0, c_1, c_2; c_3, 0 , c_4; c_5, c_6, c_7]) so basically c calues will be around and the centre point will be 0, and this matrix will be multiplied with the 9 pixels in the original image.
Finally repeat the whole process for as many as iterations variables declares, usually around 10
For an image of size 677x450 it takes around 1 minute, which I think is too much. What could change to take better advantage of numpy's functionality, or anything else that would help speed it up?
As we can see from the photos the result is a lot more smooth, even after only 2 iterations
The code is as follows:
def adaptive_smoothening(img, iterations):
M, N, K = img.shape # M: HEIGHT, N:WIDTH, K:CHANNELS
F = np.zeros([M, N, K], dtype=np.uint8)
for p in range(iterations):
print("Iteration ", p + 1)
r = img[:, :, 2]
g = img[:, :, 1]
b = img[:, :, 0]
m, n = r.shape # m: height/channel , n: width/channel
c = np.zeros([8, 1])
d = np.zeros([8, 1])
for i in range(1, m):
for j in range(1, n):
# Creating Neighborhood Indices
ip = i + 1
im = i - 1
jm = j - 1
jp = j + 1
if im < 1:
im = i
elif ip > m - 1:
ip = i - 1
if jm < 1:
jm = j
elif jp > n - 1:
jp = j - 1
d[0] = (abs(int(r[i, j]) - int(r[i, jm])) + abs(int(g[i, j]) - int(g[i, jm])) + abs(
int(b[i, j] - int(b[i, jm])))) / (3 * 255)
d[1] = (abs(int(r[i, j]) - int(r[i, jp])) + abs(int(g[i, j]) - int(g[i, jp])) + abs(
int(b[i, j] - int(b[i, jp])))) / (3 * 255)
d[2] = (abs(int(r[i, j]) - int(r[ip, j])) + abs(int(g[i, j]) - int(g[ip, j])) + abs(
int(b[i, j] - int(b[ip, j])))) / (3 * 255)
d[3] = (abs(int(r[i, j]) - int(r[im, j])) + abs(int(g[i, j]) - int(g[im, j])) + abs(
int(b[i, j] - int(b[im, j])))) / (3 * 255)
d[4] = (abs(int(r[i, j]) - int(r[im, jm])) + abs(int(g[i, j]) - int(g[im, jm])) + abs(
int(b[i, j] - int(b[im, jm])))) / (3 * 255)
d[5] = (abs(int(r[i, j]) - int(r[ip, jm])) + abs(int(g[i, j]) - int(g[ip, jm])) + abs(
int(b[i, j] - int(b[ip, jm])))) / (3 * 255)
d[6] = (abs(int(r[i, j]) - int(r[ip, jp])) + abs(int(g[i, j]) - int(g[ip, jp])) + abs(
int(b[i, j] - int(b[ip, jp])))) / (3 * 255)
d[7] = (abs(int(r[i, j]) - int(r[im, jp])) + abs(int(g[i, j]) - int(g[im, jp])) + abs(
int(b[i, j] - int(b[im, jp])))) / (3 * 255)
c = [pow(1 - float(x), 10) for x in d]
sum2 = sum(c)
F[i, j, 2] = (1 / sum2) * (
c[0] * r[i, jm] + c[1] * r[i, jp] + c[2] * r[ip, j] + c[3] * r[im, j] + c[4] * r[im, jm] +
c[5] * r[ip, jm] + c[6] * r[ip, jp] + c[7] * r[im, jp])
F[i, j, 1] = (1 / sum2) * (
c[0] * g[i, jm] + c[1] * g[i, jp] + c[2] * g[ip, j] + c[3] * g[im, j] + c[4] * g[im, jm] +
c[5] * g[ip, jm] + c[6] * g[ip, jp] + c[7] * g[im, jp])
F[i, j, 0] = (1 / sum2) * (
c[0] * b[i, jm] + c[1] * b[i, jp] + c[2] * b[ip, j] + c[3] * b[im, j] + c[4] * b[im, jm] +
c[5] * b[ip, jm] + c[6] * b[ip, jp] + c[7] * b[im, jp])
img=F
return F
image = cv2.imread("HorVerTextDoc 001.jpg", 1 )
cv2.imshow("Original", resize(image, 0.5) )
result = adaptive_smoothening(resize(image,0.5),2)
cv2.imshow("Result",result)
You do not really have to slide over your images for your task. Instead, you can create all the shifted version of your image, and do your calculations over them. Basically, you will be doing the same calculations at one-shot instead of iterating through all the pixels, which takes some much time. Here is an approach:
import numpy as np
import cv2
import matplotlib.pyplot as plt
def adaptive_smooth(img):
img = np.pad(img,((1,1),(1,1),(0,0)),mode='reflect') # add some padding so translations do not make any problem
rows,cols = img.shape[:2]
F = np.zeros_like(img)
# Translations
img_lt = cv2.warpAffine(img,np.float32([[1,0,-1],[0,1,-1]]),(cols,rows)) # top left
img_t = cv2.warpAffine(img,np.float32([[1,0,0],[0,1,-1]]),(cols,rows)) # top
img_rt = cv2.warpAffine(img,np.float32([[1,0,1],[0,1,-1]]),(cols,rows)) # right top
img_l = cv2.warpAffine(img,np.float32([[1,0,-1],[0,1,0]]),(cols,rows)) # left
img_r = cv2.warpAffine(img,np.float32([[1,0,1],[0,1,0]]),(cols,rows)) # right
img_lb = cv2.warpAffine(img,np.float32([[1,0,-1],[0,1,1]]),(cols,rows)) # left bottom
img_b = cv2.warpAffine(img,np.float32([[1,0,0],[0,1,1]]),(cols,rows)) # bottom
img_rb = cv2.warpAffine(img,np.float32([[1,0,1],[0,1,1]]),(cols,rows)) # right bottom
c_0 = (1-(np.sum(np.abs(img-img_lt),axis=2)/(255*3)))**10
c_1 = (1-(np.sum(np.abs(img-img_t),axis=2)/(255*3)))**10
c_2 = (1-(np.sum(np.abs(img-img_rt),axis=2)/(255*3)))**10
c_3 = (1-(np.sum(np.abs(img-img_l),axis=2)/(255*3)))**10
c_4 = (1-(np.sum(np.abs(img-img_r),axis=2)/(255*3)))**10
c_5 = (1-(np.sum(np.abs(img-img_lb),axis=2)/(255*3)))**10
c_6 = (1-(np.sum(np.abs(img-img_b),axis=2)/(255*3)))**10
c_7 = (1-(np.sum(np.abs(img-img_rb),axis=2)/(255*3)))**10
# fig,ax=plt.subplots(1,2,sharex=True,sharey=True)
# ax[0].imshow(c_0,cmap='gray')
# ax[1].imshow(c_7,cmap='gray')
# plt.show()
sum2 = c_0 + c_1 + c_2 + c_3 + c_4 + c_5 + c_6 + c_7
F = (1/np.dstack((sum2,sum2,sum2)))*(img_lt*np.dstack((c_0,c_0,c_0))+
img_t*np.dstack((c_1,c_1,c_1))+
img_rt*np.dstack((c_2,c_2,c_2))+
img_l*np.dstack((c_3,c_3,c_3))+
img_r*np.dstack((c_4,c_4,c_4))+
img_lb*np.dstack((c_5,c_5,c_5))+
img_b*np.dstack((c_6,c_6,c_6))+
img_rb*np.dstack((c_7,c_7,c_7)))
return F[1:-1,1:-1,:] # remove padding
img = cv2.cvtColor(cv2.imread("my_image.jpg", 1),cv2.COLOR_BGR2RGB)
F = adaptive_smooth(img) # 1st iteration
for _ in range(3): # 3 more iterations
F = adaptive_smooth(F)
F[:,:,0] = F[:,:,0]/F[:,:,0].max() # Normalize channels
F[:,:,1] = F[:,:,1]/F[:,:,1].max()
F[:,:,2] = F[:,:,2]/F[:,:,2].max()
fig,ax=plt.subplots(1,2,sharex=True,sharey=True)
ax[0].imshow(img,cmap='gray')
ax[1].imshow((F*255).astype(int),cmap='gray')
plt.show()
This image is smoothed 4 times. I hope the code is self explanatory.
EDIT: There we go. I made a mistake with sum2 in the previous version. Also I removed the data type switches in your solution, e.g., int to float at the arrays c and d. Please add them in case this is necessary for your solution.

Incorrect results when applying operations to a matrix

I am trying to make an image of a circle by transforming a numpy matrix to an image, but I am getting weird missing lines on the image when the input is 50 or more. How can I fix this?
The input determines the size of the matrix, an input of 50 makes a 50 by 50 matrix. I'm a beginner programmer, and this is my first time asking a question on stack overflow, so please don't be to harsh :) This is my code.
from PIL import Image
import itertools
np.set_printoptions(threshold=np.inf)
inp = int(input("Input size of matrix"))
dt = np.dtype(np.int8)
M = np.zeros((inp, inp), dtype=dt)
A = (list(itertools.product(range(0, inp), repeat=2)))
count1 = 0
for n in A:
x = (int(n[0]) / (inp - 1)) * 2
y = (int(n[1]) / (inp - 1)) * 2
if (x ** 2) + (y ** 2) - (2 * x) - (2 * y) <= -1:
M[int(x * (inp - 1)/2), int(y * (inp - 1)/2)] = 1
count1 += 1
print(M)
im = Image.fromarray(M * 255)
im.show()
print("Approximation of pi: " + str(4 * (count1 / inp ** 2))) ```
The problem is in this line: M[int(x * (inp - 1)/2), int(y * (inp - 1)/2)] = 1
Actually, this line assigns 1 twice in some indices and misses some indices because you are using int(). Use round() to get nearest integer. That will help. Change this line: M[int(x * (inp - 1)/2), int(y * (inp - 1)/2)] = 1 to this line: M[round(x * (inp - 1)/2), round(y * (inp - 1)/2)] = 1
Your code should look like this:
from PIL import Image
import itertools
np.set_printoptions(threshold=np.inf)
inp = int(input("Input size of matrix"))
dt = np.dtype(np.int8)
M = np.zeros((inp, inp), dtype=dt)
A = (list(itertools.product(range(0, inp), repeat=2)))
count1 = 0
for n in A:
x = (int(n[0]) / (inp - 1)) * 2
y = (int(n[1]) / (inp - 1)) * 2
if (x ** 2) + (y ** 2) - (2 * x) - (2 * y) <= -1:
M[round(x * (inp - 1)/2), round(y * (inp - 1)/2)] = 1
count1 += 1
print(M)
im = Image.fromarray(M * 255)
im.show()
print("Approximation of pi: " + str(4 * (count1 / inp ** 2)))
I think this is another solution that has the expected output also and it is an easy solution without any conversion of float to integer (for indices):
import itertools
import numpy as np
np.set_printoptions(threshold=np.inf)
inp = int(input("Input size of matrix"))
dt = np.dtype(np.int8)
M = np.zeros((inp, inp), dtype=dt)
A = (list(itertools.product(range(0, inp), repeat=2)))
# assign the center
cx,cy=int(inp/2), int(inp/2)
# assign the radius
rad=int(inp/2)
count1 = 0
for n in A:
# calculate distance of a point from the center
dist = np.sqrt((n[0]-cx)**2+(n[1]-cy)**2)
# Assign 1 where dist < rad.
if dist < rad:
M[n[0], n[1]] = 1
count1 += 1
print(M)
im = Image.fromarray(M * 255)
im.show()
print("Approximation of pi: " + str(4 * (count1 / inp ** 2)))

HSI image is equalized incorrectly in Python

I have implemented equalization for HSI color based images. I used numpy and math modules.
Firstly, I convert RGB image into HSI using this functions:
import math
import numpy as np
def rgb2hsi_px(px):
eps = 0.00000001
r, g, b = float(px[0]) / 255, float(px[1]) / 255, float(px[2]) / 255
# Hue component
numerator = 0.5 * ((r - g) + (r - b))
denominator = math.sqrt((r - g) ** 2 + (r - b) * (g - b))
theta = math.acos(numerator / (denominator + eps))
h = theta
if b > g:
h = 2 * math.pi - h
# Saturation component
num = min(r, g, b)
den = r + g + b
if den == 0:
den = eps
s = 1 - 3 * num / den
if s == 0:
h = 0
# Intensity component
i = (r + g + b) / 3
return h, s, i
def rgb2hsi(image):
hsi_image = np.zeros_like(image).astype('float')
height, width, _ = image.shape
for x in range(height):
for y in range(width):
px = rgb2hsi_px(image[x, y])
hsi_image[x, y] = px
return np.array(hsi_image)
Then I equalize an intensity value of converted image. The equalize function was implemented using this article:
import math
import numpy as np
def equalize(img):
eps = 0.000000000001
h, w, _ = img.shape
num_of_pxs = h * w
mean = 0.0
new_img = np.array(img)
while not abs(mean - 0.5) < eps:
for i in range(h):
for j in range(w):
mean += new_img[i, j, 2]
mean /= num_of_pxs
if mean != 0.5:
theta = math.log(0.5, math.e) / math.log(mean, math.e)
for x in range(h):
for y in range(w):
px = list(new_img[x, y])
px[2] = (px[2] ** theta)
new_img[x, y] = px
return new_img
After, I convert HSI image back to RGB using the next code:
import math
import numpy as np
def hsi2rgb_px(px):
h, s, i = float(px[0]), float(px[1]), float(px[2]) * 255
if 0 <= h < 2 * math.pi / 3:
b = i * (1 - s)
r = i * (1 + (s * math.cos(h)) / math.cos(math.pi / 3 - h))
g = 3 * i - (r + b)
elif 2 * math.pi / 3 <= h < 4 * math.pi / 3:
r = i * (1 - s)
g = i * (1 + (s * math.cos(h - 2 * math.pi / 3) / math.cos(math.pi / 3 - (h - 2 * math.pi / 3))))
b = 3 * i - (r + g)
elif 4 * math.pi / 3 <= h <= 2 * math.pi:
g = i * (1 - s)
b = i * (1 + (s * math.cos(h - 4 * math.pi / 3) / math.cos(math.pi / 3 - (h - 4 * math.pi / 3))))
r = 3 * i - (g + b)
else:
raise IndexError('h is out of range: {}'.format(h))
return round(r), round(g), round(b)
def hsi2rgb(image):
rgb_image = np.zeros_like(image).astype(np.uint8)
height, width, _ = image.shape
for x in range(height):
for y in range(width):
px = hsi2rgb_px(image[x, y])
rgb_image[x, y] = px
return np.array(rgb_image)
But an equalization gives an incorrect result. The size (in megabytes) of equalized image is larger than the original one. I'm not sure if it's normal but if yes, please, let me know. And another problem is that an output image has worse quality.
Here is an original image:
And the equalized image:
Can someone help me to fix my code, or reference me to similar article/question?
[UPDATE]
Driver program to test an algorithm:
import matplotlib.image as mp_img
input_img = mp_img.imread('input.bmp')
hsi_img = rgb2hsi(input_img)
equalized_img = equalize(hsi_img)
out_img = hsi2rgb(equalized_img)
mp_img.imsave('out.bmp', out_img)

how to append local variable from function to array/list in python?

How to append local variable from inside function to array/list in python?
below is my code.
I want to append corr variable to an empty array.
suppose T=[] .
its not appending and going in infinite loop.
how can I do this?
# Python Program to find correlation coefficient.
import math
# function that returns correlation coefficient.
def correlationCoefficient(X, Y, n) :
sum_X = 0
sum_Y = 0
sum_XY = 0
squareSum_X = 0
squareSum_Y = 0
i = 0
while i < n :
# sum of elements of array X.
sum_X = sum_X + X[i]
# sum of elements of array Y.
sum_Y = sum_Y + Y[i]
# sum of X[i] * Y[i].
sum_XY = sum_XY + X[i] * Y[i]
# sum of square of array elements.
squareSum_X = squareSum_X + X[i] * X[i]
squareSum_Y = squareSum_Y + Y[i] * Y[i]
z = ((float)(math.sqrt((n * squareSum_X -sum_X * sum_X)* (n * squareSum_Y -sum_Y * sum_Y))))
y = ((float)(n * sum_XY - sum_X * sum_Y))
i = i + 1
if z == 0:
corr = 0
else:
# use formula for calculating correlation coefficient.
corr=abs(y/z)
while corr<1:
T=[]
T.append(corr)
print("T",T)
return corr
# Driver function
A = [0,7.6,7.7,6.4,6.25,6.4,6.4,5.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8.3,6.4,3.2,3.2,3.25,3.25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.35,5,4.85,5.65,5.4,5.35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
B = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86]
X = [0]*5
Y = [0]*5
# the size of array.
n=5
# Function call to correlationCoefficient.
k=0
while k <= len(A):
i = k
m = 0
while i <= k+4:
X[m] = A[i]
#print("A[i]",A[i])
Y[m] = B[i]
#print("B[i]",B[i])
i = i + 1
m = m + 1
#correlationCoefficient(X, Y, 5)
print ((correlationCoefficient(X, Y, 5)))
k = k + 1
The relevant bit seems to be here:
corr=abs(y/z)
while corr<1:
T=[]
T.append(corr)
print("T",T)
return corr
You're blanking out the T array each time that while loop runs, and it will run forever if corr<1, since you never change the value of corr.
Move T=[] outside of the while i<n loop if you'd like it to stick around, and modify corr (or use an if instead) to avoid the infinite loop.

Value Error, Shapes do Not Align Python

Yeah, so this is my code in multiclass logistic regression, but when I run it it gives the error of Value Error, Shapes not aligned or whatever.
import numpy
import matplotlib.pyplot as plt
import math as mt
#normalized and feature scaled
Just loading the data set
def load():
data = numpy.loadtxt(open("housing.data.txt", "rb"), dtype="float")
m, n = data.shape
first_col = numpy.ones((m, 1))
#create new array using new parameters
data = numpy.hstack((first_col, data))
#divide each X with the max in the column
#subtract the mean of X to each element
for l in range(1, n):
max = 0.0
sum = 0.0
for j in range(0, m):
if max < data[j, l]:
max = data[j, l]
sum += data[j, l]
avg = sum / m
for j in range(0, m):
data[j, l] -= avg
data[j, l] /= max
return data
def logistic(z):
z = z[0,0]
z = z * -1
return (1.0 / (1.0 + mt.exp(z)))
def hyp(theta, x):
x = numpy.mat(x)
theta = numpy.mat(theta)
return logistic(theta * x.T)
#cost and derivative functions: TO REWRITE
#regularize using "-1000/m (hyp(theta, data[x, :-1]))"
def derv(theta, data, j):
sum = 0.0
last = data.shape[1] - 1
m = data.shape[0]
for x in range(0, m):
sum += (hyp(theta, data[x, :-1]) - numpy.mat(data[x, last])) +
numpy.mat(data[x, j])
return (sum[0,0] / m)
#regularize using " + 1000/2m(hyp(theta, data[x, :-1]))"
def cost(theta, data):
sum = 0.0
last = data.shape[1] - 1
m = data.shape[0]
for x in range(0, m):
y = data[x, last]
sum += y * mt.log(hyp(theta, data[x, :-1])) + (1 - y) * mt.log(1
- hyp(theta, data[x, :-1]))
return -1 * (sum / m)
data = load()
data1 = data[:, [10]]
data2 = data[:, [13]]
d12 = numpy.hstack((data1, data2))
data3 = data[:, [14]]
pdata = numpy.hstack((d12, data3))
print(pdata)
alpha = 0.01
theta = [10,10,10,10]
ntheta = [0,0,0,0]
delta = 50
x = 0
for l in range(0, 1000):
old_cost = cost(theta, pdata)
for y in range(0, data.shape[1] - 1):
ntheta[y] = theta[y] - alpha * derv(theta, data1, y)
for k in range(0, data.shape[1] - 1):
theta[k] = ntheta[k]
new_cost = cost(theta, data1)
delta = new_cost - old_cost
print("Cost: " + str(new_cost))
print("Delta: " + str(delta))
for r in range(0, data.shape[1]):
if hyp(theta, data1[r, :-1]) >= 0.5:
print("Predicted: 1 Actual: " + str(data1[r, data1.shape[1] - 1]))
else:
print("Predicted: 0 Actual: " + str(data1[r, data1.shape[1] - 1]))
plt.scatter(data1[:, 1], data1[:, 2])
x1 = (-1 * theta[0]) / theta[1]
x2 = (-1 * theta[0]) / theta[1]
x = range(-2, 2)
y = [((-1 * theta[0]) - (theta[1] * z) ) for z in x]
plt.plot(x, y)
plt.show()
I'm guessing it cant be plotted like this or idk

Categories

Resources