helperfunctions.py 4.24 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# -*- coding: utf-8 -*-
"""
GEPARD - Gepard-Enabled PARticle Detection
Copyright (C) 2018  Lars Bittrich and Josef Brandt, Leibniz-Institut für 
Polymerforschung Dresden e. V. <bittrich-lars@ipfdd.de>    

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program, see COPYING.  
If not, see <https://www.gnu.org/licenses/>.
"""

import numpy as np
import cv2
import os
25 26
import sys
from PyQt5 import QtWidgets, QtCore
27

28 29 30 31 32 33 34
try:
    from skimage.io import imread as skimread
    from skimage.io import imsave as skimsave
except ImportError:
    skimread = None
    skimsave = None

Josef Brandt's avatar
Josef Brandt committed
35 36 37
from .ramancom.ramanbase import RamanBase
from logging import Logger

Josef Brandt's avatar
Josef Brandt committed
38

39
def cv2imread_fix(fname, flags=cv2.IMREAD_COLOR):
40 41
    if skimread is not None:
        return skimread(fname, as_gray=(flags==cv2.IMREAD_GRAYSCALE))
42 43 44 45 46
    with open(fname, "rb") as fp:
        cont = fp.read()
        img = cv2.imdecode(np.fromstring(cont, dtype=np.uint8), flags)
        return img
    return None
47

Josef Brandt's avatar
Josef Brandt committed
48

49
def cv2imwrite_fix(fname, img, params=None):
50 51
    if skimsave is not None:
        skimsave(fname, img)
52 53
        return True

54 55 56 57 58
    pathname, ext = os.path.splitext(fname)
    if params is None:
        ret, data = cv2.imencode(ext, img)
    else:
        ret, data = cv2.imencode(ext, img, params)
59

60
    with open(fname, "wb") as fp:
61
        fp.write(data.tobytes())
62 63
    return ret

Josef Brandt's avatar
Josef Brandt committed
64

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
def polygoncovering(boundary, wx, wy):
    poslist = []
    ymin, ymax = boundary[:,1].min(), boundary[:,1].max()
    Ny = max(int(np.ceil((ymax-ymin)/wy)),1)
    dyi = wy*Ny - (ymax-ymin)
    y = ymin - .5*dyi + wy*np.arange(Ny)
    dx = np.roll(boundary[:,0],-1)-boundary[:,0]
    dy = np.roll(boundary[:,1],-1)-boundary[:,1]
    x0c, x1c = boundary[:,0].min(), boundary[:,0].max()
    x0clast, x1clast = x0c, x1c
    for i, yi in enumerate(y):
        if i==0:
            if Ny>1:
                ind = boundary[:,1]<y[1]
            else:
                ind = np.ones(boundary.shape[0], dtype=np.bool)
        elif i==Ny-1:
            ind = boundary[:,1]>yi
        else:
            ind = (boundary[:,1]>yi)&(boundary[:,1]<y[i+1])
        if i<Ny-1:
            dyc = y[i+1]-boundary[:,1]
            with np.errstate(divide='ignore'):
                ti = dyc/dy            # some elements in dy may be zero, but ti will be inf or -inf in this case -> results are ok
            indc = (ti>=0.)&(ti<1)
            xi = boundary[indc,0] + ti[indc]*dx[indc]
            x0c, x1c = xi.min(), xi.max()
            if i==0:
                x0clast, x1clast = x0c, x1c
        if np.any(ind):
            x0n, x1n = boundary[ind,0].min(), boundary[ind,0].max()
        else:
            x0n, x1n = x0c, x1c
        x0 = min([x0n,x0c,x0clast])
        x1 = max([x1n,x1c,x1clast])
        Nx = int(np.ceil((x1-x0)/wx))
        dxi = wx*Nx - (x1-x0)
        x = x0 - .5*dxi + .5*wx + wx*np.arange(Nx)
        poslist.extend([[xi,yi+.5*wy] for xi in (x if i%2==0 else x[::-1])])
        x0clast, x1clast = x0c, x1c
    return poslist
Josef Brandt's avatar
Josef Brandt committed
106 107 108 109 110 111 112 113 114 115 116 117


def getRamanControl(controlclass: RamanBase, logger: Logger) -> RamanBase:
    simulatedInterface: bool = False
    if 'simulatedInterface' in controlclass.__dict__.keys():
        if controlclass.__dict__['simulatedInterface'] == True:
            simulatedInterface = True
    if simulatedInterface:
        ramanctrl = controlclass(logger, ui=False)
    else:
        ramanctrl = controlclass(logger)
    return ramanctrl
Josef Brandt's avatar
Josef Brandt committed
118 119 120 121 122 123 124 125 126 127


def hasFTIRControl(sampleview) -> bool:
    """
    Takes a sampleview instance and inspects its ramanctrl class. Returns true if it belongs to an FTIR instrument.
    :param sampleview:
    :return:
    """
    ramanName: str = sampleview.ramanctrl.name.lower()
    return ramanName.find('ftir') != -1
128 129 130 131


def getAppFolder() -> str:
    return QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppLocalDataLocation)