import numpy as np
from matplotlib import cm
from matplotlib import pyplot as plt
import Image
from scipy import ndimage
import Image, ImageDraw
import PIL
import cv
import cv2
from scipy.ndimage import measurements, morphology
from PIL import Image
from numpy import *
from scipy.ndimage import filters
import pylab
import mahotas
from mamba import*
import mambaDraw
from PIL import Image, ImageDraw
img = np.asarray(Image.open('test.tif').convert('L'))
img = 1 * (img < 127)
draw = ImageDraw.Draw(img)
draw.line((100,200, 150,300), fill=128)
plt.imshow(img, cmap=cm.Greys_r)
plt.show()
I want to put some grid lines on image, but get the following error:
Traceback (most recent call last):
File "C:\Documents and Settings\All Users.WINDOWS\Документыline 24, in <module>
draw = ImageDraw.Draw(img)
File "C:\Python27\lib\site-packages\PIL\ImageDraw.py", line 296, in Draw
return ImageDraw(im, mode)
File "C:\Python27\lib\site-packages\PIL\ImageDraw.py", line 61, in __init__
im.load()
AttributeError: 'numpy.ndarray' object has no attribute 'load'
What is wrong with this code? How do I put a 100x100 grid on an image?
Your error here is that you convert a PIL image to a numpy array, but then you use the PIL ImageDraw library on the numpy array.
You can draw the lines in either PIL or Numpy, whichever you prefer, but you need to use Numpy to work with Numpy objects and PIL to work with PIL objects. Saullo showed how to do it in PIL, in numpy you could do:
img[:, 100:110] = 0
or for a grid 10 pixels wide, every 100:
for i in range(100,1000,100):
img[i:i+10,:] = 0
img[:,i:i+10] = 0
As a side note, your imports are a bit crazy and are messing up your namespace. For what you're doing, you can just do:
import numpy as np
import Image, ImageDraw
# and for a reasonable import of other packages you've listed
from matplotlib import cm
from matplotlib import pyplot as plt
from scipy import ndimage
import cv2
import mahotas
import mambaDraw
For example, you only need one of from numpy import * or import numpy as np, but once you've already imported it, it complicates things to reimport it as some other name.
It seems you cannot convert it to a np.ndarray. Also, you should set the width parameter to a value different than 0:
import matplotlib.pyplot as plt
from matplotlib.pyplot import cm
from PIL import Image, ImageDraw
img = Image.open( 'test.tif' ).convert('L')
draw = ImageDraw.Draw(img)
draw.line((0,200, 1000,1000), fill=123., width=4)
plt.imshow(img, cmap=cm.Greys_r)
plt.savefig('test_changed.tif')
Related
To understand the Pyton Interpreter,
MY QUESTION :
If i select the first 9 line and RUN Selected, the plt codes work…
But If i RUN all the codes, plts codes doesnt work, jump to second img.show() section…
WHY?
and
How all codes work sequential…
CODE :
from PIL import Image
import numpy as np
import matplotlib.image as gg
import matplotlib.pyplot as plt
img2 = gg.imread("C:/Users/John/Desktop/BOUTTEQA/data/1.jpg")
# print(type(img2))
# print(img2.shape)
plt.imshow(img2)
plt.colorbar()
img = Image.open("C:/Users/John/Desktop/BOUTTEQA/data/1.jpg")
print(type(img))
img.show()
print(img.format)
img1 = np.asarray(img)
import cv2
import numpy as np
from matplotlib import pyplot as plt
from scipy import ndimage
from skimage import measure, color, io
from skimage.restoration import denoise_nl_means, estimate_sigma
from skimage.filters import roberts, sobel, scharr, prewitt
from tqdm import tqdm
import os
import glob
from skimage.io import imread, imshow
from skimage import exposure
sure_bg = cv2.dilate(invert,kernel,iterations=2)
#plt.imshow(sure_bg)
dist_transform = cv2.distanceTransform(invert,cv2.DIST_L2,3)
ret2, sure_fg = cv2.threshold(dist_transform,0.2*dist_transform.max(),255,0)
sure_fg = np.uint8(sure_fg)
#plt.imshow(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)
#plt.imshow(unknown)
ret3, markers = cv2.connectedComponents(sure_fg)
markers = markers+10
markers[unknown==255] = 0
markers = cv2.watershed(img1,markers)
org_img[markers == -1] = [255,69,0]
img2 = color.label2rgb(markers, bg_label=0)
I use the function watershed from the module sci-kit image, because it has the parameter watershed_line. You can dilate the watershed lines after you detect the lines.
from skimage.segmentation import watershed
from skimage.morphology import dilation
from skimage.morphology import square
import numpy as np
markers = watershed(-dist_transform, markers, mask=sure_fg , watershed_line=True)
watershed_lines = np.zeros(shape=np.shape(markers))
watershed_lines(markers==0)=1 # ws lines are labeled as 0 in markers
watershed_lines_thick = dilation(bright_pixel, square(3))
There might be some typos since I did not check any results. But hope you get the idea. Let me know if it helps!
I'm trying to get the background of a noisy image based on this code https://www.kaggle.com/rdokov/background-removal
But, I'm getting ValueError. How to resolve this?
import glob
import cv2
from scipy import signal
import numpy as np
a = cv2.imread(glob.glob('lp_train/*.jpg')[0])
import matplotlib.pyplot as plt
a2 = np.asarray(a)/255.
aa = signal.medfilt2d(a2, 11)
plt.imshow(aa)
plt.show()
Error: ValueError: object too deep for desired array
.jpg has 3 channels, so you are sending 3-dimensional array but medfilt2d accepts 2d array.
Two ways you can solve this.
Just read as a grayscale image
import glob
import cv2
from scipy import signal
import numpy as np
a = cv2.imread(glob.glob('lp_train/*.jpg')[0], 0) # grayscale, single channel
import matplotlib.pyplot as plt
a2 = np.asarray(a)/255.
aa = signal.medfilt2d(a2, 11)
plt.imshow(aa)
plt.show()
Take a specific channel (R/G/B)
import glob
import cv2
from scipy import signal
import numpy as np
a = cv2.imread(glob.glob('lp_train/*.jpg')[0])
import matplotlib.pyplot as plt
a2 = np.asarray(a)/255.
aa = signal.medfilt2d(a2[:,:,0], 11) # a specific channel
plt.imshow(aa)
plt.show()
Both should work.
I'm trying to convert a grayscale image's pixels into a numpy array.
Working on google colab.
it shows an error saying: TypeError: 'numpy.uint8' object is not iterable
enter code here
##load Library
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from google.colab import files
from scipy import misc #to see image
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from PIL import Image
pil_im = Image.open('papa.png')
pil_imgray = pil_im.convert('LA')
img = np.array(list(pil_imgray.getdata(band=0)), float)
img.shape = (pil_imgray.size[1], pil_imgray.size[0])
plt.imshow(img)
for eachRow in img:
for eachPixel in eachRow:
x_test.append(sum(eachPixel)/3.0)
You can directly load the image using matplotlib:
plt.imread('papa.png')
or you can convert your PIL image with:
img = np.asarray(pil_im)
I'm trying to display a grayscale TIFF file using Python and MatPlotLib,
So far I have read the file this:
import scipy as N
import gdal
import sys
import matplotlib.pyplot as pyplot
try:
tif = gdal.Open('filename.tif')
tifArray = tif.ReadAsArray()
except:
print 'The file does not exist.'
sys.exit(0)
band1 = tif.GetRasterBand(1)
band2 = tif.GetRasterBand(2)
band3 = tif.GetRasterBand(3)
band1Array = band1.ReadAsArray()
band2Array = band2.ReadAsArray()
band3Array = band3.ReadAsArray()
But then I don't know what else should I do... I'm so clueless.
Anyone would help me in this?
Once you processed your file into a 2 Array, you could use ANY function in matplotlib that plots 2D arrays, e.g. cmap, imshow etc.
Here is the output with the marbles example
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
img=mpimg.imread('MARBLES.TIF ')
imgplot = plt.imshow(img)
Here is what you get if you view only band3 of the image:
imgplot2 = plt.imshow(band3Array)
plt.show()
Look further into image viewing in MPL and 2D array functions...