I need help to put a timestamp on images taken by an IP camera, I made a version of the code that save the image as a local file, then opencv write on it, now i'd like to write on it without saving it before, but i'm stucked.
This is the code:
import requests
import time
import shutil
import os
from requests.auth import HTTPBasicAuth
import cv2
from datetime import datetime
from datetime import date
import numpy as np
url = 'http://192.168.0.138/image.jpg?cidx=366981845'
user = '****'
psw = '****'
path = 'ipCameraScreen.png'
font = cv2.FONT_HERSHEY_SIMPLEX
position = (20, 30)
color = (255, 255, 255)
font_size = 0.5
font_stroke = 1
while True:
response = requests.get(url, auth=HTTPBasicAuth(user, psw), stream = True)
resp_raw = response.raw
if response.status_code == 200:
# DEFINE TIMESTAMP
current_date = str(date.today())
current_time = datetime.now().strftime("%H:%M:%S")
timestamp = (current_date + " | " + current_time)
with open(path, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
img = np.asarray(bytearray(resp_raw.read()), dtype="uint8")
img = cv2.imdecode(img, cv2.IMREAD_COLOR)
cv2.putText(img, timestamp, position, font, font_size, color, font_stroke)
cv2.imwrite(path, img)
print("Screen saved, path:", path)
time.sleep(3)
else:
print("Connection failed")
time.sleep(3)
if os.path.exists(path):
os.remove(path)
print("image removed")
time.sleep(2)
The output is:
cv2.error: OpenCV(4.5.2) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-m8us58q4\opencv\modules\imgcodecs\src\loadsave.cpp:736: error: (-215:Assertion failed) !buf.empty() in function 'cv::imdecode_'
Plz help me and sorry for easy english
Your error states that when you are trying to decode the array into img using imdecode(), the buffer is empty.
This means that in the previous line:
img = np.asarray(bytearray(resp_raw.read()), dtype="uint8")
The resp_raw.read() gives you an empty array.
I would analyze the GET-request that you perform with a tool like Postman, or just try to print the contents of resp_raw because it seems like it does not return you an image.
I solved, i just re-did the request to define resp_raw, i did this:
response = requests.get(url, auth=HTTPBasicAuth(user, psw), stream = True)
resp_raw = requests.get(url, auth=HTTPBasicAuth(user, psw), stream = True).raw
instead of this:
response = requests.get(url, auth=HTTPBasicAuth(user, psw), stream = True)
resp_raw = response.raw
Related
I trying to send individual frames to a POST infer model that receive individual images.
This is what I am trying to do:
read individual frames convert to base64 and send but isn't working
import requests
import base64
import io
from PIL import Image
import cv2
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
ret, frame = cap.read()
cv2.imshow('input', frame)
cv2.imwrite("frame.jpg", frame)
retval, buffer = cv2.imencode('.jpg', frame)
jpg_as_text = base64.b64encode(buffer)
upload_url = "".join([
"https://infer.roboflow.com/jb927-bottle-r6a6e--2",
"?access_token=AHNg55YroDzs",
"&name=frame.jpg"
])
# POST to the API
r = requests.post(upload_url, data=jpg_as_text, headers={
"Content-Type": "application/x-www-form-urlencoded"
})
# Output result
print(r.json())
if cv.waitKey(1) == ord('q'):
break
cap.release()
cv.destroyAllWindows()
It looks like the base64 encoding was happening correctly with CV2. The errors came from the post request formatting. Here is a working example:
parts = []
url_base = 'https://infer.roboflow.com/'
endpoint = '[YOUR ENDPOINT]'
access_token = '?access_token=[YOUR KEY]'
format = '&format=json'
confidence = '&confidence=50'
parts.append(url_base)
parts.append(endpoint)
parts.append(access_token)
parts.append(format)
parts.append(confidence)
url = ''.join(parts)
print(url)
frame = cv2.imread('example_frame.jpg')
retval, buffer = cv2.imencode('.jpg', frame)
jpg_as_text = base64.b64encode(buffer)
headers = {'accept': 'application/json'}
r = requests.post(url, data=jpg_as_text, headers=headers)
print(r.json())
>> my py script is running fine but when i created .py to .exe the below error is generated.
OpenCV(4.1.1) C:\projects\opencv-python\opencv\modules\videoio\src\cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): http://admin:admin#192.168.1.86/axis-cgi/mjpg/video.cgi in function 'cv::icvExtractPattern'
My py script is below and its generate.
import face_recognition
import cv2
import time
import requests
import json
from http.client import responses
from datetime import datetime
from datetime import timedelta
import sys
from truepy import License
from getmac import get_mac_address as gma
import easygui
# global variables
ChangeLayoutTime = time.localtime()
IsApiCall = False
currentTime = datetime.now()
afterTime=datetime.now()
layout_duration=0
#import json file parameters here
with open('config.json', 'r') as f:
distros_dict = json.load(f)
XiboClient_id = distros_dict['client_id']
XiboClient_secret=distros_dict["client_secret"]
XiboUrl=distros_dict["url"]
XiboDisplaygroup=distros_dict["displaygroup"]
XiboLayoutId=distros_dict["layoutId"]
IpCamStreamUrl=distros_dict["ipCamStreamUrl"]
playerIpAddress=distros_dict["playerIpAddress"]
print(IpCamStreamUrl)
# print(xiboclient_id)
# print(xiboclient_secret)
# print(xibourl)
# print(xibodisplaygroup)
# print(xibolayoutid)
# sys.exit()
# url = "'"+XiboClient_id+"'"
# print(url)
#check lic
def validateLicense():
# Load the certificate
with open('certificate.pem', 'rb') as f:
certificate = f.read()
# Load the license
with open('license.lic', 'rb') as f:
license = License.load(f, b'stech_lic_78324')
# Verify the license; this will raise License.InvalidSignatureException if
# the signature is incorrect
license.verify(certificate)
if license.data.extra != gma(ip=playerIpAddress):
print(license.data.extra)
print(gma(ip=playerIpAddress))
# shutdown the application and notify user about invalid license
easygui.msgbox("Your camera module license is invalid please contact to S-Tech team", title="Invalid License!")
sys.exit()
def __draw_label(img, text, pos, bg_color):
font_face = cv2.FONT_HERSHEY_SIMPLEX
scale = .4
color = (0, 0, 0)
thickness = cv2.FILLED
margin = 2
txt_size = cv2.getTextSize(text, font_face, scale, thickness)
end_x = pos[0] + txt_size[0][0] + margin
end_y = pos[1] - txt_size[0][1] - margin
cv2.rectangle(img, pos, (end_x, end_y), bg_color, thickness)
cv2.putText(img, text, pos, font_face, scale, color, 1, cv2.LINE_AA)
# Get a reference to webcam #0 (the default one)
video_capture = cv2.VideoCapture(IpCamStreamUrl)
# video_capture = cv2.VideoCapture("http://192.168.1.20:8080/video")
# Initialize some variables
face_locations = []
while True:
# Grab a single frame of video
ret, frame = video_capture.read()
if ret ==False:
break
# Resize frame of video to 1/4 size for faster face detection processing
small_frame = cv2.resize(frame, (0,0),fx=1,fy=1,interpolation = cv2.INTER_AREA)
# Find all the faces and face encodings in the current frame of video
face_locations = face_recognition.face_locations(small_frame, model="hog")
print(face_locations)
if face_locations is ():
break
if datetime.now().strftime("%S") == afterTime.strftime("%S"):
IsApiCall=False
# Display the results
i=0
genders=[]
ages=()
for top, right, bottom, left in face_locations:
# Scale back up face locations since the frame we detected in was scaled to 1/4 size
top *= 4
right *= 4
bottom *= 4
left *= 4
# Extract the region of the image that contains the face
face_image = frame[top:bottom, left:right]
height,width = face_image.shape[:2]
if width>144:
image='face{}.jpg'.format(i)
cv2.imwrite(image,face_image)
if datetime.now().strftime("%S") == afterTime.strftime("%S"):
IsApiCall=False
# customization by basit for layout change digisign player
if IsApiCall is False:
#check License
validateLicense()
# Access Token api
url = "http://"+XiboUrl+"/api/authorize/access_token"
data = {
'client_id': XiboClient_id,
'client_secret': XiboClient_secret,
'grant_type': 'client_credentials'
}
response = requests.request("POST", url, data=data)
obj=json.loads(response.text)
temp = obj["access_token"]
# Change layout Api
url = "http://"+XiboUrl+"/api/displaygroup/"+XiboDisplaygroup+"/action/changeLayout?envelope=1"
data = {
'layoutId': XiboLayoutId,
'changeMode': 'replace'
}
headers = {
'Authorization': 'Bearer '+temp
}
response = requests.request("POST", url, headers=headers, data=data)
print("Layout change = Success")
IsApiCall = True
# Get layout duration api
url = "http://"+XiboUrl+"/api/layout/status/"+XiboLayoutId+"?envelope=1"
headers = {
'Authorization': 'Bearer '+temp
}
response = requests.request("GET", url, headers=headers)
objj=json.loads(response.text)
temp1 = objj["data"]
layout_duration=temp1["duration"]
print("Current layout duration is " +str(layout_duration)+ " second")
currentTime = datetime.now()
afterTime = (datetime.now() + timedelta(seconds=layout_duration+10))
print("Next layout change after "+afterTime.strftime("%H")+":"+afterTime.strftime("%M")+":"+afterTime.strftime("%S"))
else:
currentTime=(datetime.now())
if (currentTime.strftime("%S") == afterTime.strftime("%S")):
IsApiCall = False
#For Vedio display window
cv2.namedWindow('Video', cv2.WINDOW_NORMAL)
cv2.imshow('Video', frame)
# Hit 'q' on the keyboard to quit!
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()
I write a script to download the 20000 images from Pixabay using Pixabay API. But the problem arises after scraping the 600th images and shows the following error:
"File "c:/Users/Dell/Desktop/python-pixabay-master/python-pixabay-master/main.py", line 26, in
pretty="true"
File "c:\Users\Dell\Desktop\python-pixabay-master\python-pixabay-master\pixabay.py", line 144, in search
raise ValueError(resp.text)
ValueError: [ERROR 400] "page" is out of valid range."
Code:
from pixabay import Image, Video
import pprint
import requests
import shutil
API_KEY = 'myAPIkeys'
image = Image(API_KEY)
j=1
for n in range(1,100):
ims = image.search(
q="education",
lang="en",
image_type="all",
orientation="all",
category="education",
min_width=0,
min_height=0,
colors="",
editors_choice="false",
safesearch="false",
order="popular",
page=n,
per_page=200,
callback="",
pretty="true"
)
#hits=ims['total']
#print(hits)
#print(ims)
#pp=pprint.PrettyPrinter(indent=4)
for i in range(0,200):
payload=ims['hits'][i]['largeImageURL']
resp = requests.get(payload, stream=True)
local_file = open(str(j)+"local_image.jpg", 'wb')
resp.raw.decode_content = True
shutil.copyfileobj(resp.raw, local_file)
del resp
print(str(j)+"URL of image: {}".format(payload))
j=j+1
#urllib.request.urlretrieve(payload,i)
#pp.pprint(ims)
#Pakshadow Hi I have tried your API in postman, You can see that in the API there is the one parameter page, So In your case your all the images are cover till page 3 so that on page 4 it's giving page is out of valid range error from pixabay.
you can try with this postman link: https://www.getpostman.com/collections/2823a8aad5ea81b55342
Import it and check that.
You can handle this error using exception.
from pixabay import Image
import requests
import shutil
API_KEY = 'API_KEY'
image = Image(API_KEY)
j=1
for n in range(1,100):
try:
ims = image.search(
q="education",
lang="en",
image_type="all",
orientation="all",
category="education",
min_width=0,
min_height=0,
colors="",
editors_choice="false",
safesearch="false",
order="popular",
page=n,
per_page=200,
callback="",
pretty="true"
)
for i in range(0, 200):
payload = ims['hits'][i]['largeImageURL']
resp = requests.get(payload, stream=True)
local_file = open(str(j) + "local_image.jpg", 'wb')
resp.raw.decode_content = True
shutil.copyfileobj(resp.raw, local_file)
del resp
print(str(j) + "URL of image: {}".format(payload))
j = j + 1
# urllib.request.urlretrieve(payload,i)
# pp.pprint(ims)
except Exception as e:
print(e)
I am trying to send a .jpg file using request and trying to decode it in
django server side.
CODE:
This is the sending side code:
import requests
import os
import base64
fPath = os.getcwd()
url = 'http://127.0.0.1:8000/submitcausedata/'
headers = {'content-type': 'application/x-www-form-urlencoded'}
path_img = fPath + '/image13.jpg'
data = open(path_img,'rb').read()
encoded_image = base64.encodestring(data)
print(encoded_image[:10])
r = requests.post(url,data=encoded_image,headers=headers)
On receiving end Code:
#csrf_exempt
def submitCauseData(request):
response_data = {}
if request.method == 'POST':
data = request.POST
myDict = dict(data)
imageStr = list(myDict.keys())
imageStr = imageStr[0]
print(imageStr[:10])
image_result = open('image.jpg', 'wb')
image_result.write(base64.b64decode(imageStr))
return HttpResponse("Page Exists")
So, the code is executing but when I try to Open the saved Image it shows the error Photo Source File missing?
The sending code output of:
print(encoded_image[:10])
----> b'/9j/4WQYRX'
The receiving side code output of:
print(imageStr[:10])
----> /9j/4WQYRX
UPDATE:
While comparing both the .jpg files using .txt conversion a lot of values in both of them are different using DiffChecker Online.
The Image Viewer on Ubuntu shows the Error while opening the .jpg on receiving side:
Error interpreting JPEG image file (Unsupported marker type 0x10)
Also:
On Sending Side:
print(len(data))
print(type(data))
print(len(encoded_image))
print(type(encoded_image))
OUTPUT:
171062
<class 'bytes'>
228084
<class 'bytes'>
On receiving side:
print(len(imageStr))
print(type(imageStr))
print(len(imagedec))
print(type(imagedec))
OUTPUT:
228083
<class 'str'>
168972
<class 'bytes'>
Does the following code work?
sending
from base64 import b64encode
from pathlib import Path
import requests
url = "http://127.0.0.1:8000/submitcausedata/"
headers = {"content-type": "application/x-www-form-urlencoded"}
encoded_image = b64encode(Path("image13.jpg").read_bytes())
print(encoded_image[:10])
r = requests.post(url, data=encoded_image, headers=headers)
receiving
from base64 import b64decode
from pathlib import Path
#csrf_exempt
def submitCauseData(request):
response_data = {}
if request.method == "POST":
imageStr = list(dict(request.POST).keys())[0]
print(imageStr[:10])
p = Path("image.jpg")
p.write_bytes(b64decode(imageStr))
return HttpResponse(f"Saved image to `{p.resolve()}`")
I found the error as when I am trying to send the class of byte string from sending side, what happens is all the '+' and '=' get converted to ' ' on receiving side.
So, by using:
Sending Side:
import requests
import os
import base64
fPath = os.getcwd()
url = 'http://127.0.0.1:8000/submitcausedata/'
headers = {'content-type': 'application/x-www-form-urlencoded'}
path_img = fPath + '/image13.jpg'
data = open(path_img,'rb').read()
encoded_image = base64.b64encode(data)
r = requests.post(url,data=encoded_image,headers=headers)
Receiving Side:
#csrf_exempt
def submitCauseData(request):
response_data = {}
if request.method == 'POST':
data = request.POST
myDict = dict(data)
imageStr = list(myDict.keys())
image = imageStr[0].replace(' ','+')
image = image.encode() + b'==='
imagedec = base64.b64decode(image)
fPath = os.getcwd()
image_result = open(fPath + '/image.jpg', 'wb')
image_result.write(imagedec)
image_result.close()
return HttpResponse("HELLO")
I solved the error.
Anyways, thanks for the help #waket-zheng :)
I am writing a python script do download training images for a project I'm working on, and I'm writing a python script to download images from image-net. I'm below is what I'm running, but I keep getting this error:
IOError: [Errno socket error] [Errno -2] Name or service not known
when it tries to go to: http://http://omusinternational.com/db3/00225/omusinternational.com/_uimages/oilRefinery.JPG.
I don't know how to fix it or tell it to throw that away and move on to the next item in my list. My code is as follows:
#!/usr/bin/python
import urllib
import cv2
import numpy as np
import os
import httplib
neg_images_link = 'http://image-net.org/api/text/imagenet.synset.geturls?wnid=n03844673'
neg_image_urls = urllib.urlopen(neg_images_link).read().decode()
pic_num = 1
for i in neg_image_urls.split('\n'):
try:
print(i)
r = urllib.urlopen(i).getcode()
print r
if r == 200:
urllib.urlretrieve(i, str(pic_num)+".jpg")
img = cv2.imread(str(pic_num)+".jpg",cv2.IMREAD_GRAYSCALE)
# should be larger than samples / pos pic (so we can place our image on it)
if img != None:
resized_image = cv2.resize(img, (100, 100))
cv2.imwrite(str(pic_num)+".jpg",resized_image)
pic_num += 1
except KeyboardInterrupt:
print "Closing"
Since it is ok for you to skip all URLs with errors you can simply catch the IOError exception and continue with the next iteration of the main for loop:
#!/usr/bin/python
import urllib
import cv2
import numpy as np
import os
import httplib
neg_images_link = 'http://image-net.org/api/text/imagenet.synset.geturls?wnid=n03844673'
neg_image_urls = urllib.urlopen(neg_images_link).read().decode()
pic_num = 1
for i in neg_image_urls.split('\n'):
try:
print(i)
try:
r = urllib.urlopen(i).getcode()
except IOError:
print "error opening " + str(i)
continue
print r
if r == 200:
urllib.urlretrieve(i, str(pic_num)+".jpg")
img = cv2.imread(str(pic_num)+".jpg",cv2.IMREAD_GRAYSCALE)
# should be larger than samples / pos pic (so we can place our image on it)
if img != None:
resized_image = cv2.resize(img, (100, 100))
cv2.imwrite(str(pic_num)+".jpg",resized_image)
pic_num += 1
except KeyboardInterrupt:
print "Closing"
break