1. 工具:
vs2015,python3.9
2. 配置c++工程环境:
1. 查看解决方案配置
这里是Release x64,
2. 打开属性管理器,在工程名下找到 Release x64文件夹,
3. 右键属性,在 VC++目录-包含目录 里面添加 Python 的 include 路径
在 库目录 里面添加Python 的 libs 路径
4. 在链接器的输入的附加依赖项中添加python39.lib文件(我的python版本是3.9),
注意: 如果第一步的解决方案配置是Debug则需要在相应的文件下面改动,在第四步添加的.lib文件也需要改成python39_d.lib。原目录下可能没有这个文件,只有python39.lib,只需将其复制并改名。
到这环境就已经准备好了 。
3. .py(有删减)
# encoding: utf-8
"""
@Time:2022/3/21 16:01
@Author: shujin sun
@Desc: 缺陷检测测试
"""
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import math
# 中文显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文
plt.rcParams['axes.unicode_minus'] = False # 显示坐标轴负号
class DetectDefect:
def __init__(self):
self.little_img_file = ''
self.big_img_file = ''
self.big_img = np.array(0)
self.little_img = np.array(0)
self.roi_img = np.array(0)
# 缺陷检测二值化结果
self.bw_img = np.array(0)
# big image 的大小
self.w = 0
self.h = 0
# 重点关注区域,即中间区域
self.roi_rect = [0, 0, 0, 0]
self.roi_patchs = []
# 缺陷检测阈值
self.thresh_value = 3000
# 所有的匹配方法
self.match_methods = ['cv.TM_CCOEFF', # 相关系数匹配法
'cv.TM_CCOEFF_NORMED', # 归一化版本
'cv.TM_CCORR', # 相关匹配法
'cv.TM_CCORR_NORMED',
'cv.TM_SQDIFF', # 平方差匹配法
'cv.TM_SQDIFF_NORMED']
def set_little_image(self, _file):
self.little_img_file = _file
self.little_img = cv.imread(_file)# cv.IMREAD_GRAYSCALE
def set_big_image(self, _file):
self.big_img_file = _file
self.big_img = cv.imread(_file)
print(self.big_img.shape)
self.h, self.w = self.big_img.shape[:2]
print('big image shape: ', self.w, self.h)
def set_thresh_value(self, thresh_value):
"""设置缺陷检测阈值门限"""
self.thresh_value = thresh_value
def conduct_edge(self, src):
'''边缘检测'''
# 计算像素中位数
gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
median_intensity = np.median(gray_img)
lower_threshold = int(max(0, (1.0 - 0.33) * median_intensity))
upper_threshold = int(min(255, (1.0 + 0.33) * median_intensity))
canny_img = cv.Canny(gray_img, lower_threshold, upper_threshold)
plt.imshow(canny_img, cmap='gray')
plt.title('canny edge detect result')
plt.xticks([]), plt.yticks([])
plt.show()
def conduct_binary_adaptive(self, src):
"""二值化操作,自适应方法"""
src = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
bw_img = cv.adaptiveThreshold(src,
255,
cv.ADAPTIVE_THRESH_MEAN_C,#cv.ADAPTIVE_THRESH_GAUSSIAN_C,
cv.THRESH_BINARY,
5,
7)
return bw_img
def conduct_binary(self, src):
"""二值化操作"""
src = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
mean_intensity = np.mean(src)
median_intensity = np.median(src)
# print('图像灰度均值、中值:', mean_intensity, median_intensity)
_, bw_img = cv.threshold(src, mean_intensity, 255, cv.THRESH_BINARY_INV+cv.THRESH_OTSU)
return bw_img
def match_template(self, big, little):
img = big.copy()
# eval函数,将字符串作为脚本代码来执行
idx = 3 # 1 or 3方法效果最好
print('选择的匹配算法:', self.match_methods[idx])
method = eval(self.match_methods[idx])
res = cv.matchTemplate(img, little, method)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
top_left = max_loc
h, w = little.shape[:2]
bottom_right = (top_left[0] + w, top_left[1] + h)
return top_left, bottom_right
if __name__ == '__main__':
# 匹配文件名称
template_img_file = r'D:\51\template2.bmp'
big_img_file = r'D:\51\sample5.bmp'
detector = DetectDefect()
detector.set_big_image(big_img_file)
detector.set_little_image(template_img_file)
detector.set_roi_rect()
detector.set_thresh_value(thresh_value=6500) # 2000, 6500
detector.show_roi_img()
detector.split_patches()
detector.defect_analyze_patchs()
4. c++文件
#include <Python.h>
#include <iostream>
#include <string>
#include <windows.h>
int main() {
Py_Initialize(); // 初始化
if (Py_IsInitialized())
std::cout << "Init Success" << std::endl;
PyRun_SimpleString("import sys"); // 在python初始化之后
PyRun_SimpleString("sys.path.append('D:/51')"); // 添加.py文件路径,注意\是转意符
system("python demo_defect_detection.py --function==__main__");
// 带参数函数 :system("python *.py --function==函数名 --参数名1==参数值1 --参数名2==参数值2")
Py_Finalize();
return 0;
}
5.运行,成功
6.总结
这个方法主要是在c++工程里使用python解释器去运行python工程。