在python中调用matlab

在python中调用matlab

在学习图像处理的基础知识,顺道学习python。用python调用matlab实现数字水印的提取与嵌入。
用PyQt5做了GUI,点击按钮调用matlab,实现水印嵌入与提取。
学习过程中发现python与matlab之间的数据转换较麻烦,现记录如下。

API安装

matlab官方提供了python调用的接口。可参考下列链接进行安装。
1.https://ww2.mathworks.cn/help/matlab/matlab_external/install-the-matlab-engine-for-python.html
2.https://ww2.mathworks.cn/help/matlab/matlab_external/get-started-with-matlab-engine-for-python.html

按照官方步骤可很顺滑的完成一系列操作,不在此赘述。后续格式转换问题纠缠数天,现解决如下。

从GUI获取图片

// get picture from QLabel

image1 = self.img1.pixmap().toImage()

1.此时为QImage格式。

QImage转为array

// QImage to array

cover = QImageToCvMat(image1)
cover_object = matlab.uint8(cover.tolist())

QImageToCvMat 为自定义函数,如下(此方法在外网找到,原地址忘了…)。

// QImage to array

def QImageToCvMat(incomingImage):
    incomingImage = incomingImage.convertToFormat(QtGui.QImage.Format.Format_RGB888)

    width = incomingImage.width()
    height = incomingImage.height()

    ptr = incomingImage.bits()
    ptr.setsize(height * width * 3)
    arr = np.frombuffer(ptr, np.uint8).reshape((height, width, 3))
    return arr

2.此时为array格式,我的matlab函数中需要输入uint8格式,在此转换,此时终于可传入matlab。

调用matlab自定义函数

  • 该.m文件需放在当前工作路径下
  • 若输出参数不为1,请定义 nargout,此值默认为1。
// call matlab

from matlab import engine

engine = matlab.engine.start_matlab()
watermrkd_img, recmessage,attack_image, attack_message, PSNR, NCC, MSSIM,PSNR_a, NCC_a, MSSIM_a=engine.dwt(cover_object, message, height,width,var, nargout=10)
     

3.调用engine,负责matlab程序的启动

matlab输出参数转换到python

// call matlab

watermrkd_img = np.array(watermrkd_img)

4.将输出参数先转换为array格式

array转QImage

//array to QImage,and show on the GUI

jpg3 = qimage2ndarray.array2qimage(watermrkd_img)
watermrkd = QtGui.QPixmap(jpg3)
self.img3.setScaledContents(True) //图片自适应QLabel
self.img3.setPixmap(watermrkd)

array2qimage为自定义方法,如下(此方法在外网找到,原地址忘了…)。

def array2qimage(array, normalize = False):
    if _np.ndim(array) == 2:
        array = array[...,None]
    elif _np.ndim(array) != 3:
        raise ValueError("array2qimage can only convert 2D or 3D arrays (got %d dimensions)" % _np.ndim(array))
    if array.shape[2] not in (1, 2, 3, 4):
        raise ValueError("array2qimage expects the last dimension to contain exactly one (scalar/gray), two (gray+alpha), three (R,G,B), or four (R,G,B,A) channels")

    h, w, channels = array.shape

    hasAlpha = _np.ma.is_masked(array) or channels in (2, 4)
    fmt = _qt.QImage.Format_ARGB32 if hasAlpha else _qt.QImage.Format_RGB32

    result = _qt.QImage(w, h, fmt)

    array = _normalize255(array, normalize)

    if channels >= 3:
        rgb_view(result)[:] = array[...,:3]
    else:
        rgb_view(result)[:] = array[...,:1] # scalar data

    alpha = alpha_view(result)

    if channels in (2, 4):
        alpha[:] = array[...,-1]
    else:
        alpha[:] = 255

    if _np.ma.is_masked(array):
        alpha[:]  *= _np.logical_not(_np.any(array.mask, axis = -1))

    return result

5.此时图片可显示在GUI上。

后记

用此API调用matlab,运行非常慢。

此项目全部代码可见https://github.com/lfreya/Digital-Watermark-use-python-and-matlab

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值