Divide image into 8x8 block : Python - python

import numpy as np
import numpy as numpy
import cv2
windowsize_r = 8
windowsize_c = 8
img = cv2.imread('image test.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
for r in range(0,gray.shape[0] - windowsize_r, windowsize_r):
for c in range(0,gray.shape[0] - windowsize_c, windowsize_c):
window = gray[r:r+windowsize_r,c:c+windowsize_c]
hist = numpy.histogram(window,bins=256)
k = cv2.waitKey(0)
if k == 27:
cv2.destroyAllWindows()
I am trying to divide am image into 8x8 blocks. My image size is 320x240. So at the end there should be 1200 blocks.my code is not showing any error but nothing is observed as output. Can anyone suggest a better solution

you need to use cv2.imshow to actually show the patch before calling waitKey. eg:
cv2.imshow('wind',window)
cv2.waitKey(0)

Related

Saving an image from pixel data in python

I am trying to create a program which will save images from pixel data obtained through openCV canny edge detection. Right now, the program saves a small image file in the correct path but the image file does not contain any of the data from the webcam.
An example of what should be saved in the image file:
picture of edge detected room
Versus what is actually saved: just a black rectangle
CODE BELOW:
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import numpy as np
from numpy import asarray
import PIL
from PIL import Image
import cv2
def LiveCamEdgeDetection_canny(image_color):
threshold_1 = 100 #LINES
threshold_2 = 50 #NOISE
image_gray = cv2.cvtColor(image_color, cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(image_gray, threshold_1, threshold_2)
return canny
# Main calling function to initialize webcam and apply edge detection
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
cv2.imshow('Live Edge Detection', LiveCamEdgeDetection_canny(frame))
#cv2.imshow('Webcam Video', frame)
#print(LiveCamEdgeDetection_canny(frame))
# Store pixel data
pixels = [LiveCamEdgeDetection_canny(frame)]
image_todraw = np.array(pixels)
image_todraw = np.reshape(image_todraw, (720, 1280))
image_todraw *= 255
image_tosave = Image.fromarray(image_todraw.astype(np.uint8))
image_tosave.save('/Users/user/Desktop/destinationFolder/RETRY.jpeg', 'JPEG')
#print(image_tosave)
if cv2.waitKey(1) == 'p': #13 Enter Key
break
cap.release() # camera release
cv2.destroyAllWindows()
I appreciate all the help you can give me!
Remove the image_todraw *= 255 line.
Below is the output:

How can I insert data from a picture into an 2d array?

I am making an AI that can play the game connect 4, from a picture of one state of the game e.g : click to see
This script below, is detecting red elements from a picture:
import cv2
import numpy as np
img = cv2.imread('connect.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
#get red color
lower_range = np.array([169, 100, 100])
upper_range = np.array([189, 255, 255])
mask = cv2.inRange(hsv, lower_range, upper_range)
cv2.imshow('image', img)
cv2.imshow('mask', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
I would like to insert these data into a 2D array to be able to use this array as a game state and determine which move the AI should make.
I have tried to find a solution on Stack Overflow and on Internet but overall I didn't find anything about it.
This is a way to read a picture and to cast it in a 2-dimensional numpy array with np.array(in_image):
import numpy as np
import skimage
from skimage import io, transform
path = "C:/my/path/"
pic = 'myPic.png'
imgName = path+pic
in_image_0 = skimage.io.imread(imgName) # read the image
in_image_1 = skimage.color.rgb2gray(in_image_0) # transform it to grey-scale
in_image_2 = skimage.transform.rescale(in_image_1, 0.5) # change the resolution
in_image_3 = np.flipud(np.array(in_image_2)) # make a numpy array and flip it up/down

Removing the lines from captcha image using python

I have captcha image as attached in this question.
I am trying to extract the text in the image. My following code is able to make all areas except the text and lines in white color
import cv2
from PIL import Image
import numpy as np
image1 = Image.open("E:\\python\\downloaded\\captcha.png").convert('L')
image2 = Image.open("E:\\python\\downloaded\\captcha.png").convert('L')
pix = image1.load()
for column in range(0, image1.height):
for row in range(0, image1.width):
if pix[row, column] >= 90:
pix[row, column] = 255
cv2.imshow("1", np.array(image2))
cv2.imshow("2", np.array(image1))
cv2.waitKey(0)
But I am trying to remove the line crossing the text, but it does not seem to work. I tried with below portion of code which is posted on other question in StackOverflow. But it does not work
def eliminate_zeros(self,vector):
return [(dex,v) for (dex,v) in enumerate(vector) if v!=0 ]
def get_line_position(self,img):
sumx=img.sum(axis=0)
list_without_zeros=self.eliminate_zeros(sumx)
min1,min2=heapq.nsmallest(2,list_without_zeros,key=itemgetter(1))
l=[dex for [dex,val] in enumerate(sumx) if val==min1[1] or val==min2[1]]
mindex=[l[0],l[len(l)-1]]
cols=img[:,mindex[:]]
col1=cols[:,0]
col2=cols[:,1]
col1_without_0=self.eliminate_zeros(col1)
col2_without_0=self.eliminate_zeros(col2)
line_length=len(col1_without_0)
dex1=col1_without_0[round(len(col1_without_0)/2)][0]
dex2=col2_without_0[round(len(col2_without_0)/2)][0]
p1=[dex1,mindex[0]]
p2=[dex2,mindex[1]]
return p1,p2,line_length
def remove_line(self,p1,p2,LL,img):
m=(p2[0]-p1[0])/(p2[1]-p1[1]) if p2[1]!=p1[1] else np.inf
w,h=len(img),len(img[0])
x=list(range(h))
y=list(map(lambda z : int(np.round(p1[0]+m*(z-p1[1]))),x))
img_removed_line=list(img)
for dex in range(h):
i,j=y[dex],x[dex]
i=int(i)
j=int(j)
rlist=[]
while i>=0 and i<len(img_removed_line)-1:
f1=i
if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
break
rlist.append(i)
i=i-1
i,j=y[dex],x[dex]
i=int(i)
j=int(j)
while i>=0 and i<len(img_removed_line)-1:
f2=i
if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
break
rlist.append(i)
i=i+1
if np.abs(f2-f1) in [LL+1,LL,LL-1]:
rlist=list(set(rlist))
for k in rlist:
img_removed_line[k][j]=0
return img_removed_line
I am new to CV and can someone help here to suggest the way?. Original and partially processed image files are attached here.
My approach is based on the fact that the line is thinner than the characters. In this example I used blurring, threshold and morphology to get rid of the line between the characters. The result is this:
import cv2
import numpy as np
image = cv2.imread('captcha.png')
image = cv2.blur(image, (3, 3))
ret, image = cv2.threshold(image, 90, 255, cv2.THRESH_BINARY)
image = cv2.dilate(image, np.ones((3, 1), np.uint8))
image = cv2.erode(image, np.ones((2, 2), np.uint8))
cv2.imshow("1", np.array(image))
cv2.waitKey(0)
You can use CV2 functions like threshold, dilate, bitwise_and and bitwise_not for removing unwanted lines from captcha
import numpy as np
import cv2
img = cv2.imread('captcha.jpg',0)
horizontal_inv = cv2.bitwise_not(img)
masked_img = cv2.bitwise_and(img, img, mask=horizontal_inv)
masked_img_inv = cv2.bitwise_not(masked_img)
kernel = np.ones((5,5),np.uint8)
dilation = cv2.dilate(masked_img_inv,kernel,iterations = 3)
ret,thresh2 = cv2.threshold(dilation,254,255,cv2.THRESH_BINARY_INV)
thresh2=cv2.bitwise_not(thresh2)
cv2.waitKey(0)
cv2.destroyAllWindows()

Depth map shows everything grey! OpenCV- Python

My code:
import cv2
import numpy as np
imgL = cv2.imread('Blender_Suzanne1.jpg')
img1 = cv2.cvtColor(imgL, cv2.COLOR_BGR2GRAY)
imgR = cv2.imread('Blender_Suzanne2.jpg')
img2 = cv2.cvtColor(imgR, cv2.COLOR_BGR2GRAY)
stereo = cv2.StereoBM_create(numDisparities = 16, blockSize = 17)
disparity = stereo.compute(img2, img1)
cv2.imshow('DepthMap', disparity)
cv2.waitKey()
cv2.destroyAllWindows()
When I run it, I see a window which is all grey? I think it is wrong.
I used this code from the OpenCV docs website.
Can anyone help?
PS: First I had some error which did not allow the output window to pop up. So, I added the two lines namely img1 and img 2 in my code.
You can display the result disparity using cv2.imshow() as well after you normalize it.
norm_image = cv2.normalize(disparity, None, alpha = 0, beta = 1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
cv2.imshow('norm_image', norm_image)
Notice the change of data type after normalizing the image. Prior to normalization disparity was of type int16. After normalization it is float32 (mentioned within the function cv2.normalize())
Instead of using imshow use matplotlib to visualization as per the documentation. Also you can convert image into gray in the same line you read the image as follows.
import cv2
from matplotlib import pyplot as plt
imgL = cv2.imread('Blender_Suzanne1.jpg',0)
imgR = cv2.imread('Blender_Suzanne2.jpg',0)
stereo = cv2.StereoBM_create(numDisparities = 16, blockSize = 17)
disparity = stereo.compute(imgL, imgR)
plt.imshow(disparity,'gray')
plt.show()

How to convert a python numpy array to an RGB image with Opencv 2.4?

I have searched for similar questions, but haven't found anything helpful as most solutions use older versions of OpenCV.
I have a 3D numpy array, and I would like to display and/or save it as a BGR image using OpenCV (cv2).
As a short example, suppose I had:
import numpy, cv2
b = numpy.zeros([5,5,3])
b[:,:,0] = numpy.ones([5,5])*64
b[:,:,1] = numpy.ones([5,5])*128
b[:,:,2] = numpy.ones([5,5])*192
What I would like to do is save and display b as a color image similar to:
cv2.imwrite('color_img.jpg', b)
cv2.imshow('Color image', b)
cv2.waitKey(0)
cv2.destroyAllWindows()
This doesn't work, presumably because the data type of b isn't correct, but after substantial searching, I can't figure out how to change it to the correct one. If you can offer any pointers, it would be greatly appreciated!
You don't need to convert NumPy array to Mat because OpenCV cv2 module can accept NumPyarray.
The only thing you need to care for is that {0,1} is mapped to {0,255} and any value bigger than 1 in NumPy array is equal to 255. So you should divide by 255 in your code, as shown below.
img = numpy.zeros([5,5,3])
img[:,:,0] = numpy.ones([5,5])*64/255.0
img[:,:,1] = numpy.ones([5,5])*128/255.0
img[:,:,2] = numpy.ones([5,5])*192/255.0
cv2.imwrite('color_img.jpg', img)
cv2.imshow("image", img)
cv2.waitKey()
You are looking for scipy.misc.toimage:
import scipy.misc
rgb = scipy.misc.toimage(np_array)
It seems to be also in scipy 1.0, but has a deprecation warning. Instead, you can use pillow and PIL.Image.fromarray
The images c, d, e , and f in the following show colorspace conversion they also happen to be numpy arrays <type 'numpy.ndarray'>:
import numpy, cv2
def show_pic(p):
''' use esc to see the results'''
print(type(p))
cv2.imshow('Color image', p)
while True:
k = cv2.waitKey(0) & 0xFF
if k == 27: break
return
cv2.destroyAllWindows()
b = numpy.zeros([200,200,3])
b[:,:,0] = numpy.ones([200,200])*255
b[:,:,1] = numpy.ones([200,200])*255
b[:,:,2] = numpy.ones([200,200])*0
cv2.imwrite('color_img.jpg', b)
c = cv2.imread('color_img.jpg', 1)
c = cv2.cvtColor(c, cv2.COLOR_BGR2RGB)
d = cv2.imread('color_img.jpg', 1)
d = cv2.cvtColor(c, cv2.COLOR_RGB2BGR)
e = cv2.imread('color_img.jpg', -1)
e = cv2.cvtColor(c, cv2.COLOR_BGR2RGB)
f = cv2.imread('color_img.jpg', -1)
f = cv2.cvtColor(c, cv2.COLOR_RGB2BGR)
pictures = [d, c, f, e]
for p in pictures:
show_pic(p)
# show the matrix
print(c)
print(c.shape)
See here for more info: http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#cvtcolor
OR you could:
img = numpy.zeros([200,200,3])
img[:,:,0] = numpy.ones([200,200])*255
img[:,:,1] = numpy.ones([200,200])*255
img[:,:,2] = numpy.ones([200,200])*0
r,g,b = cv2.split(img)
img_bgr = cv2.merge([b,g,r])
This is due to the fact that cv2 uses the type "uint8" from numpy. Therefore, you should define the type when creating the array.
Something like the following:
import numpy
import cv2
b = numpy.zeros([5,5,3], dtype=numpy.uint8)
b[:,:,0] = numpy.ones([5,5])*64
b[:,:,1] = numpy.ones([5,5])*128
b[:,:,2] = numpy.ones([5,5])*192
If anyone else simply wants to display a black image as a background, here e.g. for 500x500 px:
import cv2
import numpy as np
black_screen = np.zeros([500,500,3])
cv2.imshow("Simple_black", black_screen)
cv2.waitKey(0)
The size of your image is not sufficient to see in a naked eye. So please try to use atleast 50x50
import cv2 as cv
import numpy as np
black_screen = np.zeros([50,50,3])
black_screen[:, :, 2] = np.ones([50,50])*64/255.0
cv.imshow("Simple_black", black_screen)
cv.waitKey(0)
cv.displayAllWindows()

Categories