Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleStop image from continuing in evaluation

Exit image evaluation from flow:

It is possible to stop evaluation to save time based on a specific condition e.g. a Classifier returned a defective product class and therefore further evaluation is not needed.

ended evaluation.png
  1. To stop the evaluation copy and paste the following code.

  2. Modify Program Settings part according to the classes you wish to filter.

Code Block
languagepy
def main(context):
    # List containing names of the classes that will exit the flow sooner.
    ######################## PROGRAM SETTINGS ###################################
    list_of_exit_classes = ["My Class 1", "My Class 2"]
    ######################## END PROGRAM SETTINGS ###############################
    
    for rectangle in context['detectedRectangles']:
        if rectangle['classNames'][0]['label'] in list_of_exit_classes:
            context['exit'] = True
            return

It is necessary to modify the list list_of_exit_classes based on what classes are contained in your current project that are not supposed to continue evaluating.

Expand
titleCrop image by a detected rectangle

Crop image by a detected rectangle

Useful when the image contains unnecessary elements and the goal is to focus only on a certain part.

show_crop.png

To do this:

  1. Train a Detector module (or other) to find the region of interest.

  2. Copy and paste the following code into the Code module.

  3. Modify the Program Settings part according to the class you wish to cut (or None if the rectangle does not have a class).

Code Block
languagepy
def main(context):
    ###### PROGRAM SETTINGS #########
    LABEL = "My Rectangle"
    ###### END PROGRAM SETTINGS #####
    rectangle = find_rectangle(context)
    
    x_1, x_2 = int(rectangle['x']), int(rectangle['x'] + rectangle['width'])
    y_1, y_2 = int(rectangle['y']), int(rectangle['y'] + rectangle['height'])
    
    context['image'] = context['image'][y_1:y_2, x_1:x_2]
    
def find_rectangle(context):
    for rectangle in context['detectedRectangles']:
        if LABEL is None:
            return rectangle
        if LABEL == rectangle['classNames']['label']:
            return rectangle

It is necessary to modify the LABEL variable to contain the class name (or None) of the rectangle by which you want to crop the image.

Expand
titleSave evaluated images (with or without rectangles)

Save evaluated images to folders

Useful when your goal is to inspect the evaluated images at a later time again.

Info

This code saves only the images that were evaluated as

Status
colourRed
titleng
.

To do this create a new folder you wish to save your images to. Then copy the following code into the Code module:

Code Block
languagepy
import cv2
import skimage
import numpy as np
from datetime import datetime
from pathlib import Path

RED = (0, 0, 255)
GREEN = (0, 255, 0)
BLUE = (255, 0, 0)
YELLOW = (0, 255, 255)
WHITE = (255, 255, 255)

#################################### START CODE SETTINGS #######################################

# Specify the path to the save folder, image formats, and the wanted color of rectangles
SAVE_FOLDER = r"C:\Users\Vox\Downloads"
ORIGINAL_IMAGE_FORMAT = '.png'
ANNOTATED_IMAGE_FORMAT = '.jpg'
RECTANGLE_COLOR = RED

################################# END CODE SETTINGS ####################################


def main(context):
    # Get result
    result = context['result']
    
    # When image has result TRUE, program stop.
    if result is True:
        return
    
    # Get image from context
    image = context['image']
        
    # Save Original Image
    save_image_to_disc(image, filename_prefix = 'original_', image_format = ORIGINAL_IMAGE_FORMAT)
        
    # Draw rectangles to original image
    image = draw_rectangles_to_image(image, context, BARVA_RECTANGLU)
       
    # Save Anotated Image
    save_image_to_disc(image, filename_prefix = 'anotated_', image_format = ANNOTATED_IMAGE_FORMAT)
    
def save_image_to_disc(image, filename_prefix:str = '', image_format = '.png'):
    timestamp = generate_timestamp()
    full_save_path = Path(SAVE_FOLDER).joinpath(filename_prefix + timestamp + image_format)
    cv2.imwrite(str(full_save_path), image) 

def generate_timestamp():
    timestamp = datetime.now()
    formatted_timestamp = timestamp.strftime("%Y-%m-%d_%H-%M-%S_%f")
    return formatted_timestamp

def draw_rectangles_to_image(image, context, color:tuple = (0,0,255)):
    for rect in context['detectedRectangles']:
        rect_start = (int(rect['x']),  int(rect['y']))
        rect_end = (int(rect['x'] + rect['width']),  int(rect['y'] + rect['height']))

        image = cv2.rectangle(image, rect_start, rect_end, color, 2)
        
    return image

It is necessary to modify at least SAVE_FOLDER with your path to the saving folder. Modifying ?_IMAGE_FORMAT or RECTANGLE_COLOR is not necessary.

The folder path to copy and paste is written here:

save_folder_path.png

Expand
titleSend data to S7-1200 PLC DataBlock

Send data to S7-1200 PLC

To send your custom data or data from Pekat to a PLC:

  1. Make sure that PLC has its Protection settings set up correctly via TIAportal - Same as in this example: https://snap7.sourceforge.net/snap7_client.html#1200_1500

  2. Copy and paste the code below and set correct values to all variables in Program Settings and Output Settings.

This is for sending booleans. To send other type of data:

Set up buffer to have the correct size of bits to write and update both:

bool_value and snap7.util.set_bool(buffer, 0, 0, bool_value) accordingly.

Code Block
languagepy
import snap7

#################################### START PROGRAM SETTINGS #######################################

PLC_IP = "192.100.100.1"
DATA_BLOCK_NUMBER = 1   # For example for writing to bit on datablock DB1.2 these value will be set to 1
START_BIT_OFFSET = 2    # For example for writing to bit on datablock DB1.2 these value will be set to 2

################################# END PROGRAM SETTINGS ####################################

def main(context):

    result = context['result']
    
    if result is None:
        return
        
    #################################### OUTPUT SETTINGS #######################################
    data_to_send_to_plc = result        
    ################################# START OUTPUT SETTINGS ####################################
    
    send_bool_value_to_plc_datablock(ip=PLC_IP, db_number=DATA_BLOCK_NUMBER, start_bit_offset=START_BIT_OFFSET, bool_output=data_to_send_to_plc)

def send_bool_value_to_plc_datablock(ip:str, db_number:int, start_bit_offset:int, bool_output:bool):
    plc = snap7.client.Client()
    plc.connect(ip,  0,  0)
    

        # Initialize the bytearray with one byte
        buffer = bytearray(1)
        
        # Convert the boolean value to an integer (1 for True,  0 for False)
        bool_value = int(bool_output)
        
        # Set the boolean value to the bytearray
        snap7.util.set_bool(buffer,  0,  0, bool_value)
        
        # Write the bytearray to the PLC
        plc.db_write(DATA_BLOCK_NUMBER, start, buffer)
    
    plc.disconnect()