Python 2.7 - How to compare two image? - image

In python 2.7, I want to compare 2 image to the same, How to do this? please show me step by step. Thanks!

There are many ways to do. By using some opensource Library, like OpenCV, Scikit Learn, TensorFlow.
To compare two images, you can do something like Template Matching in OpenCV
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('img.jpg', 0)
img2 = img.copy()
template = cv2.imread('img2.jpg', 0)
w, h = template.shape[::-1]
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED']
for meth in methods:
img = img2.copy()
method = eval(meth)
res = cv2.matchTemplate(img, template, method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
if method in [cv2.TM_SQDIFF or cv2. TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(img, top_left, bottom_right, 255,2)
plt.subplot(121), plt.imshow(res)
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.suptitle(meth)
plt.show()
or Histogram comparison
import cv2
import numpy as np
base = cv2.imread('test4.jpg')
test1 = cv2.imread('test3.jpg')
test2 = cv2.imread('test5.jpg')
rows,cols = base.shape[:2]
basehsv = cv2.cvtColor(base,cv2.COLOR_BGR2HSV)
test1hsv = cv2.cvtColor(test1,cv2.COLOR_BGR2HSV)
test2hsv = cv2.cvtColor(test2,cv2.COLOR_BGR2HSV)
halfhsv = basehsv[rows/2:rows-1,cols/2:cols-1].copy() # Take lower half of the base image for testing
hbins = 180
sbins = 255
hrange = [0,180]
srange = [0,256]
ranges = hrange+srange # ranges = [0,180,0,256]
ranges=None
histbase = cv2.calcHist(basehsv,[0,1],None,[180,256],ranges)
cv2.normalize(histbase,histbase,0,255,cv2.NORM_MINMAX)
histhalf = cv2.calcHist(halfhsv,[0,1],None,[180,256],ranges)
cv2.normalize(histhalf,histhalf,0,255,cv2.NORM_MINMAX)
histtest1 = cv2.calcHist(test1hsv,[0,1],None,[180,256],ranges)
cv2.normalize(histtest1,histtest1,0,255,cv2.NORM_MINMAX)
histtest2 = cv2.calcHist(test2hsv,[0,1],None,[180,256],ranges)
cv2.normalize(histtest2,histtest2,0,255,cv2.NORM_MINMAX)
for i in xrange(5):
base_base = cv2.compareHist(histbase,histbase,i)
base_half = cv2.compareHist(histbase,histhalf,i)
base_test1 = cv2.compareHist(histbase,histtest1,i)
base_test2 = cv2.compareHist(histbase,histtest2,i)
print "Method: {0} -- base-base: {1} , base-test1: {2}, base_test2: {3}".format(i,base_base,base_test1,base_test2)

Related

Regression with constraints on contribution from variables

I'm trying to develop a regression model with constraints on effect from the independent variables. So my model equation is y = a0 + a1x1 + a2x2 with 200 datapoints. What I want to achieve is sum(a1x1) over 200 datapoints should fall in certain range i.e. lb1<sum(a1x1)<ub1. I am using Gekko for the optimization part and a got stuck while applying this condition.
I am using the following code where ubdict is the dictionary for the boundaries:
m = gk.GEKKO(remote=False)
m.options.IMODE=2 #Regression mode
y = np.array(df['y']) #dependant vars for optimization
x = np.array(df[X]) #array of independent vars for optimization
n = x.shape[1] #number of variables
c = m.Array(m.FV, n+1) #array of parameters and intercept
for ci in c:
ci.STATUS = 1 #calculate fixed parameter
xp = [None]*n
#load data
xd = m.Array(m.Param,n)
yd = m.Param(value=y)
for i in range(n):
xd[i].value = x[:,i]
xp[i] = m.Var()
if ubound_dict[i] >= 0:
xp[i] = m.Var(lb=0, ub=ubdict[i])
elif ubound_dict[i] < 0:
xp[i] = m.Var(lb=ubdict[i], ub=0)
m.Equation(xp[i]==c[i]*xd[i])
yp = m.Var()
m.Equation(yp==m.sum([xp[i] for i in range(n)] + [c[n]]))
#Minimize difference between actual and predicted y
m.Minimize((yd-yp)**2)
#APOPT solver
m.options.SOLVER = 1
#Solve
m.solve(disp=True)
#Retrieve parameter values
a = [i.value[0] for i in c]
print(a)
But this is applying the constraint row-wise. What I want is something like
xp[i] = m.Var(lb=0, ub=ubdict[i])
m.Equation(xp[i]==sum(c[i]*xd[i]) over observations)
Any suggestion would be of great help!
Below is a similar problem with sample data.
Regression Mode with IMODE=2
Use the m.vsum() object in Gekko with IMODE=2. Gekko lets you write the equations once and then applies the data to each equation. This is more efficient for large-scale data sets.
import numpy as np
from gekko import GEKKO
# load data
x1 = np.array([1,2,5,3,2,5,2])
x2 = np.array([5,6,7,2,1,3,2])
ym = np.array([3,2,3,5,6,7,8])
# model
m = GEKKO()
c = m.Array(m.FV,3)
for ci in c:
ci.STATUS=1
x1 = m.Param(value=x1)
x2 = m.Param(value=x2)
ymeas = m.Param(value=ym)
ypred = m.Var()
m.Equation(ypred == c[0] + c[1]*x1 + c[2]*x2)
# add constraint on sum(c[1]*x1) with vsum
v1 = m.Var(); m.Equation(v1==c[1]*x1)
con = m.Var(lb=0,ub=10); m.Equation(con==m.vsum(v1))
m.Minimize((ypred-ymeas)**2)
m.options.IMODE = 2
m.solve()
print('Final SSE Objective: ' + str(m.options.objfcnval))
print('Solution')
for i,ci in enumerate(c):
print(i,ci.value[0])
# plot solution
import matplotlib.pyplot as plt
plt.figure(figsize=(8,4))
plt.plot(ymeas,ypred,'ro')
plt.plot([0,10],[0,10],'k-')
plt.xlabel('Meas')
plt.ylabel('Pred')
plt.savefig('results.png',dpi=300)
plt.show()
Optimization Mode (IMODE=3)
The optimization mode 3 allows you to write each equation and objective term individually. Both give the same solution.
import numpy as np
from gekko import GEKKO
# load data
x1 = np.array([1,2,5,3,2,5,2])
x2 = np.array([5,6,7,2,1,3,2])
ym = np.array([3,2,3,5,6,7,8])
n = len(ym)
# model
m = GEKKO()
c = m.Array(m.FV,3)
for ci in c:
ci.STATUS=1
yp = m.Array(m.Var,n)
for i in range(n):
m.Equation(yp[i]==c[0]+c[1]*x1[i]+c[2]*x2[i])
m.Minimize((yp[i]-ym[i])**2)
# add constraint on sum(c[1]*x1)
s = m.Var(lb=0,ub=10); m.Equation(s==c[1]*sum(x1))
m.options.IMODE = 3
m.solve()
print('Final SSE Objective: ' + str(m.options.objfcnval))
print('Solution')
for i,ci in enumerate(c):
print(i,ci.value[0])
# plot solution
import matplotlib.pyplot as plt
plt.figure(figsize=(8,4))
ypv = [yp[i].value[0] for i in range(n)]
plt.plot(ym,ypv,'ro')
plt.plot([0,10],[0,10],'k-')
plt.xlabel('Meas')
plt.ylabel('Pred')
plt.savefig('results.png',dpi=300)
plt.show()
For future questions, please create a simple and complete example that demonstrates the issue.

Complex ODE (ODEintWarning: Excess work done on this call)

I am trying to numerically solve a rather complex system of ordinary differential equations. Odeint gives error I guess for the excessive computational work. Any idea on alternatives?
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import scipy
from scipy.integrate import odeint
# declare parameters:
k1 = 2
k2 = 1.8E6
k3 = 48
k3r = 2.8e8
k4 = 1.1e6
k5 = 3
k6 = 6.6e9
k6r = 9.4
k7 = 40
k8 = 7.1
k9 = 0.25
k10 = 0.053
H = 1.28
A = 0.42 #BrO3-
C = 0.0012 #CH2(COOH)2
#define tspan and I.C.
t = np.linspace(0,50,num=5000, endpoint=False)
J0=[0,0.11,0.0012,0,0,0,0.19,0]
def adv_oregonator(j, t):
dxdt = k1*A*j[1]*H**2-k2*H*j[1]*j[0]-k3*H*A*j[0]+k3r*j[5]**2+k4*H*j[5]*(C-j[2])-2*k5*j[0]**2;
dydt = -k1*A*j[1]*H**2-k2*H*j[1]*j[0]-k6*j[3]*j[1]*H+k7*j[4]*j[6]+k9*j[7]*j[2];
dzdt = k4*H*j[5]*(C-j[2])-k9*j[7]*j[2]-k10*j[2]*j[6];
dpdt = k1*A*j[1]*H**2+2*k2*H*j[1]*j[0]+k5*j[0]**2-k6*j[3]*j[1]*H-k8*j[3]*j[6];
dudt = k6*j[3]*j[1]*H-k6r*j[4]-k7*j[4]*j[6];
dwdt = 2*k2*H*A*j[0]-2*k3r*j[5]**2-k4*H*j[5]*(C-j[2]);
dmdt = -k7*j[4]*j[6]-k8*j[3]*j[6]-k10*j[2]*j[6];
dbdt = k7*j[4]*j[6]+k8*j[3]*j[6]-k9*j[2]*j[7];
djdt = [dxdt,dydt,dzdt,dpdt,dudt,dwdt,dmdt,dbdt]
return djdt
j = odeint(adv_oregonator,J0,t)
This is the original system.
And these are the weird plots that I get when I run the script:

I use multiprocessing to search for images, but I get an error

import cv2
import numpy as np
from PIL import ImageGrab
from multiprocessing import Pool
def getGrayBase():
base = ImageGrab.grab(bbox=(0, 0, 1920, 1080))
base.save(f'Screen\\base.png')
base = f'Screen\\base.png'
rgbBase = cv2.imread(base)
grayBase = cv2.cvtColor(rgbBase, cv2.COLOR_BGR2GRAY)
return grayBase
def findPict(sabjektSearch):
grayBase=getGrayBase()
template = cv2.imread(sabjektSearch, 0)
rezult = {'flag': False, 'x': 0, 'y': 0, 'func': 0,'scroll':0}
# w, h = template.shape[::-1] # Высота ширина
# We find the center of the desired image
M = cv2.moments(template)
centr_x = int(M['m10'] / M['m00'])
centr_y = int(M['m01'] / M['m00'])
# print(f'centr {centr_x, centr_y}')
rez_search = cv2.matchTemplate(grayBase, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
# Check if the image you are looking for in the base
flag = False
for i in rez_search:
if np.amax(rez_search) > threshold:
flag = True
rezult['flag'] = flag
if flag == True:
loc = np.where(rez_search >= threshold)
for pt in zip(*loc[::-1]):
x = int(pt[0]) + centr_x
y = int(pt[1]) + centr_y
rezult['x'] = x
rezult['y'] = y
nameFunc = sabjektSearch.split('\\')[-1]
rez = f'{nameFunc} - YES ' if flag else f' {nameFunc} - no '
print(rez,end=" ")
return rezult
arr_pick_all=[f'Screen\p1.png',f'Screen\\p2',f'Screen\p3.png',f'Screen\p4.PNG',f'Screen\p5.png',f'Screen\\p6.png']
if __name__ == '__main__':
p = Pool(len(arr_pick_all))
rezult=p.map(findPict,arr_pick_all)
print()
print(rezult.get(timeout=1))
p.close()
p.join()
Finds 1-3 pictures, but with a large number an error occurs
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'

Convolution of image with kernel gives white output

I've a code that filters image with 3x3 Gaussian kernel but the output is white. GuassianFilter function works(output is correct) but there is problem in convolution function.
What would be the problem? I checked code again but couldn't solve this.
import math
import numpy as np
import cv2
path="funny_hats.jpg"
inputImage = cv2.imread(path,cv2.IMREAD_GRAYSCALE)
def GaussianFilter(img):
#generating 3x3 kernel
kernel = np.ones((3,3), dtype='float64')
size = 3
mean = int(size/2)
sigma = 1 # standart deviation is 1
sumAll = 0
for i in range(size):
for j in range(size):
kernel[i,j] = math.exp(-1* ((math.pow( (i-mean)/sigma, 2.0) + (math.pow((j-mean)/sigma, 2.0)) ) / (2* math.pow(sigma,2)) )) / (sigma * math.pow(2*math.pi, 1/2))
sumAll += kernel[i,j]
# normalizing kernel
for i in range(size):
for j in range(size):
kernel[i,j] /= sumAll
# Filter image with created kernel
img = convolution(img, kernel) # filtered image
print(img)
cv2.imshow('aa', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
def convolution(img, dest):
res = img
[h,w] = img.shape
[kh, kw] = dest.shape # kernel shape
kr = int(kh/2) # kernel radius
res = np.zeros(img.shape)
for i in range(0+kr,h-kr):
for j in range(0+kr,w-kr):
for k in range(-1 * kr, kr + 1):
for m in range(-1 * kr, kr + 1):
res[i,j] += dest[k,m]*img[i+k, j+m]
res[:,0] = res[:, 1]
res[:,w-1] = res[:, w-2]
res[0,:] = res[1,:]
res[h-1,:] = res[h-2,:]
return res
GaussianFilter(inputImage)
res = img
This is wrong. You must create image where all pixels will be zero (black).

pymc3 improving theano compile time before sampling

I'm working with this hierarchical Bayesian model:
import pymc3 as pm
import pandas as pd
import theano.tensor as T
categories = pd.Categorical(df.cat)
n_categories = len(set(categories.codes))
cat_idx = categories.codes
with pm.Model()
mu_a = pm.Normal('mu_a', 0, sd=100**2)
sig_a = pm.Uniform('sig_a', lower=0, upper=100)
alpha = pm.Normal('alpha', mu=mu_a, sd=sig_a, shape=n_categories)
betas = []
for f in FEATURE_LIST:
mu_b = pm.Normal('mu_b_%s' % f, 0, sd=100**2)
sig_b = pm.Uniform('sig_b_%s' % f, lower=0, upper=100)
betas.append(pm.Normal('beta_%s' % f, mu=mu_b, sd=sig_b, shape=n_categories))
logit = 1.0 / (1.0 + T.exp(-(
sum([betas[i][cat_idx] * X_train[f].values for i, f in enumerate(FEATURE_LIST)])
+ alpha[cat_idx]
)))
y_est = pm.Bernoulli('y_est', logit, observed=df.y)
start = pm.find_MAP()
trace = pm.sample(2000, pm.NUTS(), start=start, random_seed=42, njobs=40)
I would imagine that replace my python list of priors and individual additions and multiplications with proper Theano code (perhaps using T.dot?) would improve the performance of the call to sample. How do I set this up in Theano correctly? I imagine that I need to do something like shape=(n_features, n_categories) for my priors, but I'm not sure how to do the category index in the dot product.

Resources