This is an article of ZOZO Technologies # 1 Advent Calendar 2019. Yesterday was "Knowledge required when using a Mac in a Windows team" by @e_tyubo. I also have many opportunities to use multiple OSs properly, so it was very helpful. I was introduced as "a playful engineer who brings a drone to the development training camp", but this time I would like to write a solid content that is closer to business lol
The smart factory team to which I belong is in charge of business improvement and automation that occur in the clothing production process. Among them, there are many image processing-related projects, and the genres vary from those directly related to business to those that are closer to research.
When developing based on such diverse requests, we judge "whether efficiency and automation are necessary in the first place", "whether it can be realized immediately", and "whether there is a business advantage", and prioritize development. You need to prescribe.
However, since it is the apparel industry that originally has few automation cases and data, it is not uncommon to find out if you do not try it. Therefore, it does not have to be 100%, so it is convenient to have some index results.
This time, I will introduce the process used to show the results in prototyping in the above situations. If you are too close to the business, it may be difficult to put out the contents, so this article only touches on the basic processing.
When I try image processing experimentally, I create a "data folder" and a "result folder" in the workspace, and input and output are performed in these folders. It is easier for me personally to put only the images I want to process in a folder and process them, so I take this form.
import os.path
import datetime
import cv2
#constant
#data folder
DATA_PATH = "data"
#result folder
RESULT_PATH = "result"
def main():
#Get the current directory
current_path = os.getcwd()
#get the data directory
data_path = os.path.join(current_path, DATA_PATH)
#get the data directory
result_path = os.path.join(current_path, RESULT_PATH)
#Get a list of files directly under the directory
data_list = os.listdir(data_path)
for file in data_list:
#Get file extension
file_name, ext = os.path.splitext(file)
#When the extension is png or jpeg
if ext == u'.png' or ext == u'.jpg' or ext == u'.jpeg':
#Load image
input_path = os.path.join(data_path, file)
image = cv2.imread(cv2.samples.findFile(input_path))
#Write some processing here
#Named using time so that the file name is not covered
output_path = os.path.join(result_path, create_time_path(file_name, "extension"))
#Save image
cv2.imwrite(output_path, "Output image")
return
#Output a unique file path including time
def create_time_path(file_name, ext):
#Get the current time
time = datetime.datetime.now()
#Create a path
path = file_name + time.strftime("%Y%m%d%H%M%S") + ext
return path
if __name__ == '__main__':
main()
The Gaussian filter uses a Gaussian distribution to add weights according to how far it is from the pixel of interest. The larger the standard deviation value, the greater the smoothing effect.
Before the main processing of a noisy image, it is applied as a preparation. Try adjusting the kernel size according to the nature of the image you want to process.
#Gaussian filter kernel size(Odd)
GAUSSIAN_KERNEL = (5, 5)
#Gaussian filter
def exc_gaussian_blur(image):
#Apply Gaussian filter
gaussian_image = cv2.GaussianBlur(image, GAUSSIAN_KERNEL, 0)
return gaussian_image
To briefly explain the contents, the processing is performed in the flow of "(1) Noise reduction and differentiation", "(2) Detection of the maximum position of the gradient", and "(3) Threshold processing". The output result will change depending on the setting value, so please adjust it according to the nature of the image you want to process.
#canny edge detection threshold minimum
CANNY_MIN = 100
#canny edge detection threshold maximum
CANNY_MAX = 150
#Edge image generation function
def exc_canny_blur(image):
#Apply Canny filter
edgeImg = cv2.Canny(image, CANNY_MIN, CANNY_MAX)
return edgeImg
A process that adds a pixel to the target pixel that touches the background or hole of the image. It is often used together with shrinkage processing, mainly for noise reduction.
#Expansion / reduction filter kernel size
MAX_MIN_KERNEL = (10, 10)
#Expansion / reduction filter execution count
MAX_MIN_ITERATION = 10
#Expansion processing function
def exc_dilate(image):
#Expansion filter application
dstImg = cv2.dilate(image, MAX_MIN_KERNEL, MAX_MIN_ITERATION)
return dstImg
A process that strips a pixel around the target pixel that touches the background or hole of the image. It is often used together with shrinkage processing, mainly for noise reduction.
#Expansion / reduction filter kernel size
MAX_MIN_KERNEL = (10, 10)
#Expansion / reduction filter execution count
MAX_MIN_ITERATION = 10
#Shrinkage processing function
def exc_erode(image):
#Shrink filter application
dstImg = cv2.erode(image, MAX_MIN_KERNEL, MAX_MIN_ITERATION)
return dstImg
A transformation that combines arbitrary linear transformation and translation. I often use it to rotate images.
#Affine transformation
def exc_affine(dx, dy, image):
#Affine transformation(Translation)
affine_mat = np.float32([[1, 0, dx], [0, 1, dy]])
height, width = image.shape[:2]
image_affine = cv2.warpAffine(image, affine_mat, (width, height))
return image_affine
#Image rotation
def exc_rotation(angle, scale, image):
#Get center position
center = tuple(np.array([image.shape[1] * 0.5, image.shape[0] * 0.5]))
#Calculation of rotation transformation matrix
affine_mat = cv2.getRotationMatrix2D(center, angle, scale)
#Affine transformation(rotation)
height, width = image.shape[:2]
rotation_image = cv2.warpAffine(image, affine_mat, (width, height), cv2.INTER_CUBIC)
return rotation_image
When moving 100 vertically and horizontally.
Set the scaling status to 10.
The processing introduced above is used in different combinations depending on the target image. You can respond to various scenes by changing the combination, so please customize it for yourself.
ZOZO Technologies # 1 Advent Calendar 2019 Tomorrow is "Calculate using Rust" by @ niba1122.
Recommended Posts