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:
Related
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
Then I read some jpg file, this way
image = imread('aa.jpg')
As result I get dataframe with numbers from 1 to 255
I can resize it this way:
from cv2 import resize
image = resize(image, (256, 256)
But then I doing same think with png, result not desired.
image = imread('aa2.png') # array with number within 0-1 range
resize(image, (256,256)) # returns 1 channel image
resize(image, (256,256, 3)) # returns 3 channel image
Weird image
But imshow(image)
cv2.imread reads the image in 3 channel by default instead of 4. Pass the parameter cv.IMREAD_UNCHANGED to read your PNG file and then try to resize it as shown in the code below.
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread('Snip20190412_12.png', cv.IMREAD_UNCHANGED)
print(img.shape) #(215, 215, 4)
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height))
print(res.shape)#(430, 430, 4)
plt.imshow(res)
I guess is some problem with your image or code.
Here a free image to try: https://pixabay.com/vectors/copyright-free-creative-commons-98566/
Maybe you have problem with libpng, check this answers: libpng warning: iCCP: known incorrect sRGB profile
Check this simple code that works on PNG images.
import cv2 as cv
image = cv.imread("foto.png")
if __name__ == "__main__":
while True:
image = cv.resize(image,(200,200))
cv.imshow("prueba",image)
key = cv.waitKey(10)
if key == 27:
cv.destroyAllWindows()
break
cv.destroyAllWindows()
Able to show the image through matplotlib, however unable to do it through cv2.imshow. The shape of the image is not consistent with opencv required formats. Require help on changing on changing it so it can be shown by the command cv2.imshow
test.jpg is a random jpg file from web
import numpy as np
import cv2
import matplotlib.pyplot as plt
import ReadIM
img = cv2.imread('test.jpg')
vbuff, vatts = ReadIM.extra.get_Buffer_andAttributeList('test.im7')
v_array, vbuff = ReadIM.extra.buffer_as_array(vbuff)
print (np.shape(v_array))
print (v_array[0])
print (np.shape(img))
# Showing image through matplotlib
plt.imshow(v_array[0])
plt.show()
#Showing image through cv2
cv2.imshow('image',v_array[0])
cv2.waitKey(0)
cv2.destroyAllWindows()
# Remove memory
#del(vbuff)
ReadIM.DestroyBuffer(vbuff)
ReadIM.DestroyAttributeListSafe(vatts)
test.im7
Normalizing the image to (0,255) will do the trick
img = cv2.normalize(img, None, 255,0,cv2.NORM_MINMAX,dtype = cv2.CV_8UC1)
cv2.imshow('image',img)
i used the following code to capture a face using Haar cascade classifier but still have not get full head image
from imutils.video import WebcamVideoStream
import os
import time
from datetime import datetime
from imutils.video import FPS
import cv2
cascadePath = "/home/pi/opencv-3.3.0/data/haarcascades/haarcascade_frontalface_default.xml"
eye_cascade = cv2.CascadeClassifier('/home/pi/opencv-3.3.0/data/haarcascades/haarcascade_eye.xml')
faceCascade = cv2.CascadeClassifier(cascadePath);
fn = input('Enter your Folder name: ')
os.system("mkdir "+fn)
vs = WebcamVideoStream(src=0).start()
while 1:
time.sleep(0.05)
frame = vs.read()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(gray, 1.1, 6)
for (x,y,w,h) in faces:
cv2.imwrite(fn+"/"+ datetime.now().strftime("%H:%M:%S.%f") + ".jpg", gray[y:y+h+30,x:x+w+20])
cv2.imshow('frame',frame)
key = cv2.waitKey(1) & 0xFF
In order to capture the head also you need to decrease the initial point where you start cropping the face.
In your code you have used gray[y:y+h+30,x:x+w+20].
y takes into account the height of the cropped face. This is where you need to decrease the initial cropping point.
x denotes the width of the face which you do not need to change.
Conclusion: Change it to gray[y-20:y+h, x:x+w] in line 22 within cv2.imwrite().
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)