In order to make sure every pixel in the image is actually shown you need to make sure to draw the image such that one pixel in the image is larger or equal one pixel on screen.
Example: If the figure has a dpi of 100 and is 4.5 inch heigh and you take 10% margin on each side, an image with 350 pixels will be shown correctly,
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(6,4.5))
plt.subplots_adjust(top=0.9, bottom=0.1)
img=np.random.rand(350,350)
dx, dy = 10,10
grid_color = -1
img[:,::dy] = grid_color
img[::dx,:] = grid_color
plt.imshow(img,'gray',vmin=-1,vmax=1)
plt.show()

If the figure has a dpi of 100 and is 3.2 inch heigh and you take 10% margin on each side, an image with 350 pixels will not show every pixel and hence you get the following output,
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(6,3.2))
plt.subplots_adjust(top=0.9, bottom=0.1)
img=np.random.rand(350,350)
dx, dy = 10,10
grid_color = -1
img[:,::dy] = grid_color
img[::dx,:] = grid_color
plt.imshow(img,'gray',vmin=-1,vmax=1)
plt.show()

So in order to obtain a grid even for the latter case, this answer is a better approach. You can create a grid and set the linewidth of the grid, such that is always 0.72 points (=1pixel @ 100dpi).
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
plt.figure(figsize=(6,3.2))
plt.subplots_adjust(top=0.9, bottom=0.1)
img=np.random.rand(350,350)
plt.imshow(img,'gray',vmin=-1,vmax=1)
plt.minorticks_on()
plt.gca().xaxis.set_minor_locator(matplotlib.ticker.MultipleLocator(10))
plt.gca().yaxis.set_minor_locator(matplotlib.ticker.MultipleLocator(10))
plt.grid(which="both", linewidth=0.72,color="k")
plt.tick_params(which="minor", length=0)
plt.show()
