Notice: 函数 _load_textdomain_just_in_time 的调用方法不正确twentyseventeen 域的翻译加载触发过早。这通常表示插件或主题中的某些代码运行过早。翻译应在 init 操作或之后加载。 请查阅调试 WordPress来获取更多信息。 (这个消息是在 6.7.0 版本添加的。) in /var/www/html/wp/wp-includes/functions.php on line 6121
2021 年 10 月 – 技术栈点

OPENCV多幅图像拼合函数

实现效果:

iShot2021-10-21 16.31.21

python实现:

import cv2
import numpy as np

def stackImages(scale,imgArray):
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range ( 0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank]*rows
        hor_con = [imageBlank]*rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor= np.hstack(imgArray)
        ver = hor
    return ver
  
  
img = cv2.imread("image.jpg")
imgBlur = cv2.GaussianBlur(img, (7, 7), 1)#高斯模糊处理
imgGray = cv2.cvtColor(imgBlur, cv2.COLOR_BGR2GRAY)#转换成灰度图
imgStack = stackImages(0.4,([img, imgBlur, imgGray],
                            [imgGray, img, imgBlur]))
cv2.imshow("Result", imgStack)

C++实现

#include <vector>
#include "opencv2/opencv.hpp"
#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

cv::Mat StackImage(float scale, std::vector< std::vector<cv::Mat> > images){
    int rows = images.size();//获取行数
    int cols = images[0].size();//获取列数

    if (images[0][0].empty()){
        cout<<"image not found"<<endl;
        cv::Mat blankImage = cv::Mat::zeros(cv::Size(1, 1), CV_8UC3);;
        return blankImage;
    }

    int width=images[0][0].cols, height=images[0][0].rows;  //获取第一张图像高度和宽度,剩余图像以此为基准
    int targetWidth=round(width*scale), targetHeight=round(height*scale);   //获取单张图像缩放后的宽度和高度
    int resultWidth=targetWidth*cols, resultHeight=targetHeight*rows;   //计算目标拼图的高度和宽度
    int targetType = CV_8UC3;

    cv::Mat result = cv::Mat::zeros(cv::Size(resultWidth, resultHeight), CV_8UC3);
    
    for (int i=0; i<rows; ++i){
        for (int j=0;j<cols; ++j){
            
            if (images[i][j].empty()){
                continue;
            }

            cv::Mat dstImage;
            int imgWidth=images[0][0].cols, imgHeight=images[0][0].rows;
            cv::resize(images[i][j], dstImage, cv::Size(targetWidth, targetHeight));
            cout<<dstImage.type()<<endl;
            switch(dstImage.type()){
                case 0:cv::cvtColor(dstImage, dstImage, CV_GRAY2BGR); break;
                case 4:cv::cvtColor(dstImage, dstImage, CV_BGRA2BGR); break;
            }
            //dstImage.convertTo(dstImage, CV_8UC3);

            CvRect rect = cvRect( targetWidth*j, targetHeight*i, targetWidth, targetHeight);
            cv::Mat dstMat = result(rect);
            dstImage.colRange(0, dstImage.cols).copyTo(dstMat);
        }
    }
    
    return result;
}


int main(){
    cv::Mat img=cv::imread("image.png");
    
    /*C++11标准可以这么写*/
    vector<vector<cv::Mat> > images { 
        {img, img, img} ,
        {img, img, img} 
    };
    /*备用方法*/
    //vector<vector<cv::Mat> > images(1, vector<cv::Mat>(3));
    //images[0][0]=img;
    //images[0][1]=img;
    //images[0][2]=img;

    cv::Mat imgStack = StackImage(0.6f, images);
    cv::imshow("result", imgStack);
    cv::waitKey();
    cv::destroyAllWindows();
    return 0;
}

【串口调试】通过串口发送变量数据,上位机python实时绘图

stm32通过uart发送数据帧给上位机,上位机使用python接收数据并绘制折线图

//debug发送数据函数
#define DEBUG_PLT_START_BIT 0xfe
#define DEBUG_PLT_STOP_BIT 0xff

typedef enum dataType{
	INT8_T = 0x10,
	INT16_T = 0x11,
	INT32_T = 0x12,
	
	UINT8_T = 0x00,
	UINT16_T = 0x01,
	UINT32_T = 0x02,
	
	FLOAT = 0x20,

        CLEAR = 0x80, 

}dataType_t;

//用于清空图中原有数据(程序初始化时用)
void ClearDebugPltData(int8_t dataId){
	uint8_t sendData[8]={DEBUG_PLT_START_BIT, 0, CLEAR, 0, 0, 0, 0, DEBUG_PLT_STOP_BIT};
	sendData[1] = dataId;
	sendData[2] = CLEAR;
	HAL_UART_Transmit(&DEBUG_UART, sendData, 8, 100);
	HAL_Delay(1);
}

void SendDebugPltData(int8_t dataId, dataType_t dataType, void* data, uint8_t dataLen){
	uint8_t sendData[8]={DEBUG_PLT_START_BIT, 0, 0, 0, 0, 0, 0, DEBUG_PLT_STOP_BIT};
	sendData[1] = dataId;
	sendData[2] = dataType;
	memcpy(sendData + 3, data, dataLen);
	HAL_UART_Transmit(&DEBUG_UART, sendData, 8, 100);
}

C发送数据代码示例

float data=10.05f;
SendDebugPltData(1, FLOAT, &data, sizeof(data));

uint8_t data=100;
SendDebugPltData(1, UINT8_T, &data, sizeof(data));

int32_t data=-3100;
SendDebugPltData(1, INT32_T, &data, sizeof(data));

python接收串口数据并绘图代码

#-*- coding: utf-8 -*-
 
# uart+绘图多线程

import threading
import serial
import matplotlib.pyplot as plt
import numpy as np
import time
import re
import struct
import sys

class MyThread(threading.Thread):
    def __init__(self,func,args=()):
        super(MyThread,self).__init__()
        self.func = func
        self.args = args
    def run(self):
        self.result = self.func(*self.args)
    def get_result(self):
        try:
            return self.result
        except Exception:
            return None


comport = "/dev/cu.usbserial-0001"#COM名称
baudrate = "115200"#波特率
maxLen=100#最大显示数据量


HEX="0123456789abcdef"
START_BIT=0xfe
END_BIT=0xff
lock = threading.Lock()
t = [0]
m = [0]
i = 0
intdata = 0
data = ''
count = 0



def initSerial():
    global serialport
    serialport = serial.Serial(comport, int(baudrate), timeout=1)
    if serialport.isOpen():
        print("open success")
    else:
        print("open failed")

def SerialReceive():
    global t,m,serialport,i
    rawData=b''
    numData=b''

    while True:
        while True:
            ch = serialport.read()
            #print(type(ch),type(rawData))
            rawData+=ch

            if(len(rawData)>8):
                rawData=rawData[len(rawData)-8:]
            #print(rawData)
            if (len(rawData)==8) and (rawData[0]==START_BIT) and (rawData[7]==END_BIT):
                break
        numData=rawData[3:7]#数值位
        dataId=rawData[1]#数据编号
        dataType=rawData[2]#数据类型

        

        signed=(dataType & 0x10) > 0#是否含符号位
        decimal=(dataType & 0x20) > 0#是否为小数

        if dataType==0x80:
            lock.acquire()
            i=0
            t=[]
            m=[]
            plt.cla()
            lock.release()
            rawData=b''
            continue

        print(f"dataId:{dataId} signed:{signed} decimal:{decimal} dataType:{dataType}")
        #print(f"{HEX[numData[0]//16]}{HEX[numData[0]%16]}{HEX[numData[1]//16]}{HEX[numData[1]%16]}{HEX[numData[2]//16]}{HEX[numData[2]%16]}{HEX[numData[3]//16]}{HEX[numData[3]%16]}")

        if not decimal:
            if (dataType & 0x0f == 0x00):
                data = int.from_bytes(numData[:1], byteorder='little', signed = signed)
            elif (dataType & 0x0f == 0x01):
                data = int.from_bytes(numData[:2], byteorder='little', signed = signed)
            else:
                data = int.from_bytes(numData[:4], byteorder='little', signed = signed)
        else:
            
            data = struct.unpack('f', numData)[0]

        i = i+1
        print(i,data)

        lock.acquire()
        t.append(i)
        m.append(data)

        lock.release()
        rawData=b''
        
    
    
def StartSerialReceive():
    thread = MyThread(SerialReceive,args=())
    thread.setDaemon(True)
    thread.start()
    
def initPlt():
    plt.grid(True) # 添加网格
    plt.ion()   # interactive mode
    plt.figure(1)
    plt.xlabel('times')
    plt.ylabel('data')
    plt.title('Diagram of UART data by Python')


def drawPlt():
    global t,m
    if not lock.locked():
        lock.acquire()
        if len(t) > maxLen:  # 清除画布,重新开始,避免数据量过大导致卡顿。
            t = t[len(t)-maxLen:]
            plt.cla()
        if len(m) > maxLen:  # 清除画布,重新开始,避免数据量过大导致卡顿。
            m = m[len(m)-maxLen:]
            plt.cla()
        lock.release()
    lock.acquire()
    plt.plot(t, m, '-r')
    plt.draw()
    lock.release()


print(sys.argv)

if (len(sys.argv) > 2):
    if (sys.argv[1]=="-len"):
        maxLen = int(sys.argv[2])
        print(f"最大数据长度修改为{maxLen}")
initSerial()
initPlt()
StartSerialReceive()


while True:
    drawPlt()
    plt.pause(0.002)