I have trained and deployed End Point of a custom object detection model using new Vertex AI in google cloud. When I test the model on cloud I see perfect bounding boxes on a image. But when I send request to the end point using python, the bounding boxes gotten in response seems to be incorrect.
Please note I am multiplying with width and height.
My code:-
import base64
from google.cloud import aiplatform
import cv2
from google.cloud.aiplatform.gapic.schema import predict
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="C:\\Users\\tarunmis\\Downloads\\first-cascade-315219-ccaaa402f837.json"
IMAGE_PATH = "C:\\Users\\tarunmis\\Desktop\\p2.jpg"
def predict_image_object_detection_sample(
project: str="MY STR",
endpoint_id: str="MY ID",
filename: str=IMAGE_PATH,
location: str = "us-central1",
api_endpoint: str = "us-central1-aiplatform.googleapis.com",
):
# The AI Platform services require regional API endpoints.
client_options = {"api_endpoint": api_endpoint}
# Initialize client that will be used to create and send requests.
# This client only needs to be created once, and can be reused for multiple requests.
client = aiplatform.gapic.PredictionServiceClient(client_options=client_options)
with open(filename, "rb") as f:
file_content = f.read()
# The format of each instance should conform to the deployed model's prediction input schema.
encoded_content = base64.b64encode(file_content).decode("utf-8")
instance = predict.instance.ImageObjectDetectionPredictionInstance(
content=encoded_content,
).to_value()
instances = [instance]
# See gs://google-cloud-aiplatform/schema/predict/params/image_object_detection_1.0.0.yaml for the format of the parameters.
parameters = predict.params.ImageObjectDetectionPredictionParams(
confidence_threshold=0.5, max_predictions=10,
).to_value()
endpoint = client.endpoint_path(
project=project, location=location, endpoint=endpoint_id
)
response = client.predict(
endpoint=endpoint, instances=instances, parameters=parameters
)
print("response")
print(" deployed_model_id:", response.deployed_model_id)
# See gs://google-cloud-aiplatform/schema/predict/prediction/image_object_detection.yaml for the format of the predictions.
predictions = response.predictions
preds = list()
print(response)
for prediction in predictions:
preds.append(dict(prediction))
return preds
# [END aiplatform_predict_image_object_detection_sample]
predictions = predict_image_object_detection_sample()
prediction = predictions[0]
image = cv2.imread(IMAGE_PATH,1)
h,w,c = image.shape
boxes = prediction['bboxes']
confs = prediction["confidences"]
for box,conf in zip(boxes,confs):
x1 = int(w*box[0])
y1 = int(h*box[1])
x2 = int(w*box[2])
y2 = int(h*box[3])
if conf>0.1:
cv2.circle(image,(x1,y1),5,(0,0,255),cv2.FILLED)
cv2.circle(image, (x2, y2), 5, (255, 0, 0), cv2.FILLED)
cv2.rectangle(image,(x1,y1),(x2,y2),(0,255,0))
cv2.imshow("img",image)
cv2.waitKey()
And the response is:-
predictions {
struct_value {
fields {
key: "bboxes"
value {
list_value {
values {
list_value {
values {
number_value: 0.678395331
}
values {
number_value: 0.779298723
}
values {
number_value: 0.645786881
}
values {
number_value: 0.683837295
}
}
}
values {
list_value {
values {
number_value: 0.18701905
}
values {
number_value: 0.287654519
}
values {
number_value: 0.627796173
}
values {
number_value: 0.669630647
}
}
}
}
}
}
fields {
key: "confidences"
value {
list_value {
values {
number_value: 0.813014865
}
values {
number_value: 0.748636127
}
}
}
}
fields {
key: "displayNames"
value {
list_value {
values {
string_value: "plate"
}
values {
string_value: "plate"
}
}
}
}
fields {
key: "ids"
value {
list_value {
values {
string_value: "66451184247898112"
}
values {
string_value: "66451184247898112"
}
}
}
}
}
}
deployed_model_id: "1371469231836626944"
h and w should be the other way round and so should x2 and y1:
w,h,c = img.shape
...
x1 = int(w*boxes[0])
x2 = int(w*boxes[1])
y1 = int(h*boxes[2])
y2 = int(h*boxes[3])
Related
Want to validate in Karate framework
For the below Json What I want to validate is,
if "isfilter_regex":0 then "msgtype": "##regex ^[A-Za-z0-9_.]-/*"
or if "isfilter_regex":1 then "msgtype": "#string"
(when isfilter_regex = 1 then msgtype must be a regular expression)
In my case number of candidate s in candidates array is 180+
I tried lot of things I ended up failing can anybody help me here?
{
"candidates":[
{
"candidate":{
"name":"Alex",
"category":[
{
"category_name":"APCMRQ",
"filters":[
{
"isfilter_regex":0,
"msgtype":"APCMRQ"
}
]
},
{
"category_name":"BIDBRQ",
"filters":[
{
"isfilter_regex":1,
"msgtype":"'(AMSCNQ(_[A-Za-z0-9]{1,3}){0,3})'"
}
]
}
]
}
}
]
}
I tried below way which works only when idex specified, but what to do if I want to do this check for entire array?,
* def msgRegexValue = response.candidates[150].candidate.category[0].filters[0].isfilter_regex
* def actualFilter = response.candidates[150].candidate.category[0].filters[0]
* def expectedFilter = actualFilter
* def withRegex =
"""
{
"isfilter_regex": 0,
"msgtype": '##regex ^[A-Za-z0-9_.]*-*/*'
}
"""
* def withoutRegex =
"""
{
"isfilter_regex": 1,
"msgtype": '##string'
}
"""
* def expected = msgRegexValue == 0 ? withRegex: withoutRegex
* match actualFilter == expected
When reading JSON queries with triple quotes, python converts the """ to '. For example, in this elasticsearch query:
query = {
"size": 0,
"aggregations": {
"responses.counts": {
"scripted_metric": {
"init_script": "state.responses = ['error':0L,'success':0L,'other':0L]",
"map_script": """
def code = doc['response.keyword'].value;
if (code.startsWith('5') || code.startsWith('4')) {
state.responses.error += 1 ;
} else if(code.startsWith('2')) {
state.responses.success += 1;
} else {
state.responses.other += 1;
}
"""
}
}
}
}
the function inside map_script gets completely distorted. How do I store this JSON object (serialize) so it can be correctly passed on to elasticsearch?
new to groovy and coding in general. Trying to do the following:
(I have looked at many previous Q&As in stackoverflow but none of the solutions I found seem to work)
I have the following JSON from which I need to get a list/string of supplier names i.e. output should be something like : "supplier 1, supplier 2, supplier 3"
[
{
"id":217564,
"created-at":"2020-01-22T08:59:57+00:00",
"state":"submitted",
"supplier":
{
"name":"supplier 1"
}
},
{
"id":217565,
"created-at":"2020-01-22T09:00:00+00:00",
"state":"submitted",
"supplier":
{
"name":"supplier 2"
}
},
{
"id":217566,
"created-at":"2020-01-22T09:00:48+00:00",
"state":"submitted",
"supplier":
{
"name":"supplier 3"
}
}
]
I used the following groovy script to print out all the supplier names in a list:
import groovy.json.*;
#CustomScriptAction(
input = ['json_response'],
output = 'suppliers'
)
def CustomScriptAction14()
{
def object = new JsonSlurper().parseText(json_response.toString())
def suppliers = "No suppliers"
if(object != null && !object.isEmpty())
{
for(def i =0; i<object.size();i++)
{
suppliers = RString.of(object[i].'supplier'.name.toString());
}
}
return suppliers
}
I got the output: "supplier 3"
The issue is that this script is only giving me the last supplier in the loop instead of iterating through the entire loop and printing out all the suppliers. So I tried a different script:
import groovy.json.*;
#CustomScriptAction(
input = ['json_response'],
output = 'suppliers'
)
def CustomScriptAction14()
{
def object = new JsonSlurper().parseText(json_response)
def suppliers = object.findAll { it.value instanceof List }
.values()
.flatten()
.collect { [it.'supplier'.'name'] }
}
return suppliers
But with this I get a blank response.
What am I doing wrong?
Well this ended up working:
import groovy.json.*;
#CustomScriptAction(
input = ['json_response'],
output = 'suppliers'
)
def customScript()
{
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(json_response.toString())
suppliers = RString.of(object.'supplier'.'name'.toString())
}
How can I print out the max length of each field in CSV file?
Example input:
foo,bar
abcd,12345
def,234567
Expected output:
Max length of fields: [4, 6]
The following piece of code will do the job:
def txt='''foo,bar
abcd,12345
def,234567'''
txt.split('\n').collect { it.split(',') }.transpose().collect { field -> field.max { it.size() } }*.size()
In the end, I used this:
def csv = new File('./myfile.csv').text
def max = [ ] as ArrayList
csv.eachLine { line, count ->
def params = line.split(',')
// skip the header line
if (count > 0)
{
params.eachWithIndex() { p, index ->
if (p.length() > max[index] ) {
max[index] = p.length()
}
}
}
}
println "Max length of fields: ${max}"
I want to put the value of a variable (==i) in a textfield, so that its value is shown in the textfield, i.e., changing from 1 to 10.
def sb = new SwingBuilder()
def th = Thread.start {
for(i in 1..10) {
sleep 2000
}
}
def Pan = sb.panel(layout: new BorderLayout()) {
sb.panel(constraints: BorderLayout.NORTH){
gridLayout(cols: 2, rows: 3)
textField id:'tf', text: ?
}
}
You can do that with the doOutside method of SwingBuilder, which allows to run a closure outside the EDT. The code below does what you are trying to do (with a table layout instead of a grid layout).
import groovy.swing.SwingBuilder
import static javax.swing.JFrame.EXIT_ON_CLOSE
import java.awt.*
def swingBuilder = new SwingBuilder()
swingBuilder.edt {
def message
def setMessage = { String s -> message.setText(s) }
frame(title: 'Example', size: [200, 150], show: true, locationRelativeTo: null, defaultCloseOperation: EXIT_ON_CLOSE) {
borderLayout(vgap: 5)
panel(constraints: BorderLayout.CENTER, border: emptyBorder(10)) {
tableLayout(cellpadding: 5) {
tr {
td {
label 'Value' // text property is default, so it is implicit.
}
td {
message = textField(id: 'tf', columns: 5, text: '0')
}
}
}
}
}
doOutside {
for (i in 1..10) {
sleep 1000
edt { setMessage(String.valueOf(i)) }
}
}
}