예제 #1
0
def normalize_in_place(img: ndarray, by="area"):
    """Normalize a ndarray in place. Only for float type arrays.

    Args:
        img: Input ndarray.

        by : Used normalization method. Available methods are:\n
                * 'area': normalize to sum one
                * 'peak': normalize to maximum value
                * 'l2': normalize by L2 norm of the array
    """
    param_list = ["area", "peak", "l2"]

    if img.dtype not in [np.float16, np.float32, np.float64]:
        raise ValueError(
            "In place normalization only allowed for float arrays.")

    if by not in param_list:
        raise ValueError(
            "Specified argument type is not one of the recognized "
            f"methods: {param_list}")

    if by == "area":
        img /= img.sum()

    elif by == "peak":
        img /= img.max()

    elif by == "l2":
        img /= np.linalg.norm(img, ord='fro')
예제 #2
0
def get_demosaiced(img: ndarray,
                   pattern: str = 'GRBG',
                   method: str = 'bilinear') -> ndarray:
    """Get a demosaiced RGB image from a raw image.

    This function is a wrapper of the demosaicing functions supplied by the
    ``color_demosaicing`` package.

    Args:
        img: Input image, greyscale, of shape (x,y).

        pattern: Bayer filter pattern that the input image is modulated with.
            Patterns are: 'RGGB', 'BGGR', 'GRBG', 'GBRG'.

            Default: 'GRBG'

        method: Algorithm used to calculate the demosaiced image.\n
            * 'bilinear': Simple bilinear interpolation of color values
            * 'malvar2004': Algorithm introduced by Malvar et. al. [R3]_
            * 'menon2007': Algorithm introduced by Menon et. al. [R4]_,


    Returns:
        Demosaiced RGB-color image of shape (x,y,3) of
        dtype :class:`numpy.float64`.

    References:
        .. [R3]  H.S. Malvar,  Li-wei He, and  R. Cutler (2004).
           High-quality linear interpolation for demosaicing of
           Bayer-patterned color images.
           IEEE International Conference on Acoustics, Speech, and Signal
           Processing, Proceedings. (ICASSP '04).
           DOI: 10.1109/ICASSP.2004.1326587

        .. [R4]  D. Menon, S. Andriani, G. Calvagno (2007).
           Demosaicing With Directional Filtering and a posteriori Decision.
           IEEE Transactions on Image Processing (Volume: 16, Issue: 1)
           DOI: 10.1109/TIP.2006.884928

    """

    param_list = ["bilinear", "malvar2004", "menon2007"]

    # Do demosaicing with specified method
    if method not in param_list:
        raise ValueError(
            f"The specified method {method} is none of the supported "
            f"methods: {param_list}.")

    elif method == "bilinear":
        return demosaicing_CFA_Bayer_bilinear(img.astype(np.float64),
                                              pattern=pattern)

    elif method == "malvar2004":
        return demosaicing_CFA_Bayer_Malvar2004(img.astype(np.float64),
                                                pattern=pattern)

    elif method == "menon2007":
        return demosaicing_CFA_Bayer_Menon2007(img.astype(np.float64),
                                               pattern=pattern)
예제 #3
0
def build_model(maze: ndarray, lr=0.001):
    model = Sequential()
    model.add(Dense((maze.__sizeof__()), input_shape=(64,)))
    model.add(PReLU())
    model.add(Dense(maze.__sizeof__()))
    model.add(PReLU())
    model.add(Dense(Constants.num_actions))
    model.compile(optimizer='adam', loss='mse')
    return model
예제 #4
0
    def run(self, img: ndarray, road_ellipse: Ellipse,
            angle: float) -> ndarray:
        x_center = int(img.shape[1] / 2)

        if angle > 0:
            img_debug = cv2.arrowedLine(
                img.copy(),
                pt1=(x_center, 50),
                pt2=(int(x_center + (20 * math.sin(angle * math.pi / 2))),
                     int(50 - (20 * math.cos(angle * math.pi / 2)))),
                color=(255, 20, 100),
                thickness=3,
                tipLength=0.5)
        else:
            img_debug = cv2.arrowedLine(
                img.copy(),
                pt1=(x_center, 50),
                pt2=(int(x_center - (20 * math.sin(-1 * angle * math.pi / 2))),
                     int(50 - (20 * math.cos(angle * math.pi / 2)))),
                color=(255, 20, 100),
                thickness=3,
                tipLength=0.5)
        if not road_ellipse:
            return img

        if road_ellipse.axes:
            reduced_axes = (int(road_ellipse.axes[0] / 5),
                            int(road_ellipse.axes[1] / 5))
        else:
            reduced_axes = (1, 1)
        green = int(road_ellipse.trust * 255)
        red = 255 - int(road_ellipse.trust * 255)
        img_debug = cv2.ellipse(img_debug,
                                center=road_ellipse.center,
                                axes=reduced_axes,
                                angle=road_ellipse.angle,
                                startAngle=0,
                                endAngle=360,
                                color=(20, green, red),
                                thickness=2)
        img_debug = cv2.circle(img_debug,
                               center=road_ellipse.center,
                               radius=5,
                               color=(255, 0, 0))
        img_debug = cv2.putText(img=img_debug,
                                text='{0:.2f}'.format(angle),
                                org=(10, 10),
                                fontFace=cv2.FONT_HERSHEY_PLAIN,
                                fontScale=1,
                                color=(255, 255, 255))
        return img_debug
예제 #5
0
def lasso_hetero_gs(X: ndarray, y: ndarray, lam: ndarray, w_init: ndarray, tol: float,
                    verbose: bool=False) -> ndarray:
    n, m = X.shape
    scaler = np.sqrt(np.sum(X ** 2, axis=0))
    X = X / scaler
    w = w_init.copy()

    if m == 0:
        return w

    def subgradient(w, r):
        return -r @ X + lam * np.sign(w)

    r = 0
    for t in count():
        if t % 100 == 0:
            r = y - X @ w

        sg = subgradient(w, r)
        eff_lam = lam * (w == 0)
        abs_g = abs(soft_threshold(sg, eff_lam))
        i = np.argmax(abs_g)

        if verbose:
            print("lasso_hetero_gs: step: {}\tgrad: {}".format(t, abs_g[i]))
            if t % 100 == 99:
                import pdb
                pdb.set_trace()
        if abs_g[i] / np.fabs(w) < tol:
            break

        w_i_new = soft_threshold(w[i] + X[:, i] @ r, lam[i])
        r += (w[i] - w_i_new) * X[:, i]
        w[i] = w_i_new
    return w * scaler
예제 #6
0
def normalize(img: ndarray, by="area", dtype=np.float64) -> ndarray:
    """Get a normalized copy of an ndarray, e.g. an image or kernel.
    The returned array will be a float.

    Args:
        img: Input ndarray.

        by : Used normalization method. Available methods are:\n
            * 'area': normalize to sum one
            * 'peak': normalize to maximum value
            * 'l2': normalize by L2 norm of the array

        dtype : Output dtype. Either np.float16, np.float32 or np.float64.
                If input is float, output will be of same word size.

    Returns:
        Normalized array of same shape as input array.

    See Also:
        Based on :func:`normalize_in_place()`.

    """
    if img.dtype not in [np.float16, np.float32, np.float64]:
        d_type = dtype
    else:
        d_type = img.dtype

    res = img.copy().astype(d_type)
    normalize_in_place(res, by=by)

    return res
예제 #7
0
    def create_combined_fits_file(cls, name: str,
                                  data: ndarray,
                                  file_type_code: int,
                                  image_type_string: str,
                                  exposure: float,
                                  temperature: float,
                                  filter_name: str,
                                  binning: int,
                                  comment: str):
        """Write a new FITS file with the given data and name.
        Create a FITS header in the file by copying the header from a given existing file
        and adding a given comment"""

        #  Create header
        header = fits.Header()
        header["FILTER"] = filter_name
        header["COMMENT"] = comment
        header["EXPTIME"] = exposure
        header["CCD-TEMP"] = temperature
        header["SET-TEMP"] = temperature
        header["XBINNING"] = binning
        header["YBINNING"] = binning
        header["PICTTYPE"] = file_type_code
        header["IMAGETYP"] = image_type_string

        # Create primary HDU
        data_16_bit = data.round().astype("i2")
        primary_hdu = fits.PrimaryHDU(data_16_bit, header=header)

        # Create HDUL
        hdul = fits.HDUList([primary_hdu])

        # Write to file
        hdul.writeto(name, output_verify="fix", overwrite=True, checksum=True)
예제 #8
0
def denoise_image_huber(img: ndarray,
                        n_iter: int,
                        w_lambda: Union[ndarray, float] = 0.5) -> ndarray:
    """Primal-dual algorithm for minimization of TV-Huber-norm-L1-functional.
    Algotirhm is based on [R1]_.

    Discrete functional:

    - TV_Huber-L1: min_x( ||_nabla x||_h + lambda*||x - f||_1 )

    Args:
        img:
            Input image.

        n_iter:
            Number of iterations

        w_lambda:
            Weight factor of data term. Pixel-wise weight is possible.

    Returns:
        The filtered image of the same shape as the input image.

    """
    L2 = 8.0
    alpha = 0.05
    gamma = 5
    delta = alpha

    mu = 2 * np.sqrt(gamma * delta) / np.sqrt(L2)
    tau = mu / 2 / gamma
    theta = 1 / (1 + mu)
    sigma = mu / 2 / delta

    # Iterative primal-dual algorithm
    u = img.copy()
    y = _nabla(u)
    for i in range(n_iter):
        # Optimize dual variable ( prox_f ) TV
        y = y + sigma * _nabla(u)

        # Projection (TV with huber norm)
        y = _prox_tv(y, 1 + sigma * alpha) / (1 + sigma * alpha)

        # Optimize primal variable ( prox_g )
        u_new = u - tau * _nablaT(y)

        # l1-norm (shrink)
        u_new = _prox_l1(u_new, img, w_lambda * tau)

        # Extrapolate
        u = u_new + theta * (u_new - u)

        # Break if max accuracy reached
        # if (np.abs(u[:]-u_new[:])).sum() < tol:
        #     print(i)
        #     break

    return u
예제 #9
0
    def _apply_horizon(self, img: ndarray):
        horizon = int(img.shape[0] * self._config.horizon)
        if horizon < 1:
            return img.copy(), img.copy()

        img_horizon = cv2.rectangle(img=img.copy(),
                                    pt1=(0, 0),
                                    pt2=(img.shape[1], horizon - 1),
                                    thickness=cv2.FILLED,
                                    color=(0, ))
        img_debug = cv2.cvtColor(img.copy(), cv2.COLOR_GRAY2RGB)
        img_debug = cv2.line(img=img_debug,
                             pt1=(0, horizon - 1),
                             pt2=(img.shape[1], horizon - 1),
                             thickness=2,
                             color=(0, 0, 250))
        return img_horizon, img_debug
예제 #10
0
def add_visual_box(img_orig: ndarray, left: int, top: int, right: int,
                   bottom: int):
    img = img_orig.copy()
    max_value = np.max(img)
    img[top:bottom + 2, left:left + 3, :] = max_value  # left
    img[top:bottom + 2, right - 1:right + 2, :] = max_value  # right
    img[top:top + 3, left:right + 2, :] = max_value  # top
    img[bottom - 1:bottom + 2, left:right + 2, :] = max_value  # bottom
    return img
예제 #11
0
def denoise_image_tvl1(img: ndarray,
                       n_iter: int,
                       w_lambda: Union[ndarray, float] = 0.5) -> ndarray:
    """Primal-dual algorithm for minimization of TV-L1-functional.
    Algotirhm is based on [R1]_.

    Discrete functional:

    - TV-L1: min_x( ||_nabla x||_1 + lambda*||x - f||_1 )

    Args:
        img:
            Input image.

        n_iter:
            Number of iterations

        w_lambda:
            Weight factor of data term. Pixel-wise weight is possible.

    Returns:
        The filtered image of the same shape as the input image.

    """

    u = img.copy()
    y = _nabla(u)

    L2 = 8.0
    tau = 0.02
    sigma = 1.0 / (L2 * tau)
    theta = 1.0

    # Iterative primal-dual algorithm
    for i in range(n_iter):
        # Calculate gradient
        u_grad = _nabla(u)

        # Optimize dual variable ( prox_f ) TV
        y = y + sigma * u_grad
        # Projection
        y = _prox_tv(y)

        # Optimize primal variable ( prox_g )
        u_new = u - tau * _nablaT(y)
        # l1-norm (shrink) (TV-l1 denoising)
        u_new = _prox_l1(u_new, img, w_lambda * tau)

        # Extrapolate
        u = u_new + theta * (u_new - u)

        # Break if max accuracy reached
        # if (np.abs(u[:]-u_new[:])).sum() < tol:
        #     print(i)
        #     break

    return u
예제 #12
0
 def draw_image_debug(self, centroid: Centroid, img_gray: ndarray,
                      shape: Shape, value: int) -> ndarray:
     img_debug = cv2.cvtColor(img_gray.copy(), cv2.COLOR_GRAY2RGB)
     font = cv2.FONT_HERSHEY_SIMPLEX
     cv2.putText(img_debug, str(value), (20, 20), font, 1, (255, 255, 255),
                 1, cv2.LINE_AA)
     cv2.circle(img_debug, centroid, 3, (0, 100, 100), 1)
     cv2.drawContours(img_debug, shape, -1, (240, 40, 100), 1)
     self._video_frame = img_debug
     return img_debug
예제 #13
0
 def run(self, img: ndarray, shapes: List[Shape]) -> ndarray:
     try:
         img_debug = img.copy()
         nb_contours = self._config.number_centroids_to_use
         colors = self._get_colors_index(nb_contours)
         for i in range(nb_contours):
             cv2.drawContours(img_debug, shapes[i:i + 1], -1, colors[i], 2)
         return img_debug
     except:
         logging.exception("Unexpected error")
         return np.zeros(img.shape)
예제 #14
0
def calculate_feature(array: ndarray):
    # assert array.shape[0] > 10 and array.shape[1] > 10
    out = []
    unit_width, unit_height = array.shape[1] // 10, array.shape[0] // 10
    for row in range(10):
        for column in range(10):
            out.append(array[row * unit_height:(row + 1) * unit_height + 1,
                             column * unit_width:(column + 1) * unit_width +
                             1, ].mean())
    out.append(array.mean())
    return out
예제 #15
0
    def _process_contours(self,
                          img_gray: ndarray) -> (ndarray, List[Centroid]):
        shapes, centroids = self._contours_detector.process_image(img_gray)

        img = cv2.cvtColor(img_gray.copy(), cv2.COLOR_GRAY2RGB)
        for centroid in centroids:
            cv2.circle(img, centroid, 3, (0, 100, 100), 1)

        cv2.drawContours(img, shapes, -1, (240, 40, 100), 1)

        logger.debug("Centroids founds: %s", centroids)
        return img, shapes, centroids
예제 #16
0
    def run(self, img_gray: ndarray) -> int:
        try:
            (_, binary) = cv2.threshold(img_gray.copy(),
                                        self._config.centroid_value, 255, 0,
                                        cv2.THRESH_BINARY)
            (shapes, centroids) = self._contours_detector.process_image(
                img_binarized=binary)

            if not centroids:
                return self._config.centroid_value

            value = img_gray.item((centroids[0][1], centroids[0][0]))
            self._config.centroid_value = value
            logger.debug("Threshold value estimate: %s", value)

            self.draw_image_debug(centroids[0], img_gray, [shapes[0]], value)
            return value
        except Exception:
            import numpy
            logging.exception("Unexpected error")
            return self._config.centroid_value
예제 #17
0
def lasso_hetero(X: ndarray, y: ndarray, lam: ndarray, w_init: ndarray, tol: float, return_obj: bool=False,
                 copy_X: bool=True, max_iter: int=100, verbose: bool=False) -> Union[ndarray, Tuple[ndarray, float]]:
    n, m = X.shape
    scale = np.sqrt(np.sum(X ** 2, axis=0))
    if copy_X:
        X = X / scale
    else:
        X /= scale

    lam = lam / scale

    w = w_init.copy()

    if m == 0:
        return w

    r = y - X @ w
    gap = np.inf
    for t in range(max_iter):
        w_max = 0
        d_w_max = 0

        for i in range(m):
            w_i_new = soft_threshold(w[i] + X[:, i] @ r, lam[i])
            d_w = w[i] - w_i_new
            r += d_w * X[:, i]
            w[i] = w_i_new

            w_max = max(w_max, np.fabs(w_i_new))
            d_w_max = max(d_w_max, np.fabs(d_w))

        gap = d_w_max / (w_max + 1e-16)

        if verbose:
            print("lasso_hetero_gs: step: {}\tgrad: {}".format(t, gap))

        if gap < tol:
            break
    else:
        warnings.warn("not converged after {} iterations; gap: {}".format(max_iter, gap), ConvergenceWarning)

    ww: ndarray = w / scale
    if return_obj:
        obj: float = 0.5 * np.sum(r) + np.sum(lam * np.fabs(ww))
        return ww, obj
    else:
        return ww
예제 #18
0
    def run(self, img: ndarray) -> ndarray:
        try:
            rows, columns, channel = np.shape(img)
            middle = int(columns / 2)
            mask = np.zeros(img.shape, np.uint8)
            central_zone_delta = int(
                ((columns / 100) * self._config.central_zone_percent) / 2)

            # Draw safe zone
            cv2.rectangle(img=mask,
                          pt1=(middle - central_zone_delta, 0),
                          pt2=(middle + central_zone_delta, rows),
                          color=(0, 255, 0),
                          thickness=cv2.FILLED)

            out_zone_delta = int(
                ((columns / 100) * self._config.out_zone_percent) / 2)

            # Draw dangerous zone
            cv2.rectangle(img=mask,
                          pt1=(0, 0),
                          pt2=(out_zone_delta, rows),
                          color=(255, 0, 0),
                          thickness=cv2.FILLED)
            cv2.rectangle(img=mask,
                          pt1=(columns - out_zone_delta, 0),
                          pt2=(columns, rows),
                          color=(255, 0, 0),
                          thickness=cv2.FILLED)

            # Apply mask
            img_debug = cv2.addWeighted(src1=img.copy(),
                                        alpha=0.7,
                                        src2=mask,
                                        beta=0.3,
                                        gamma=0)

            # Draw central axes
            img_debug = cv2.line(img=img_debug,
                                 pt1=(middle, 0),
                                 pt2=(middle, img.shape[1]),
                                 color=(0, 0, 255),
                                 thickness=2)
            return img_debug
        except:
            logging.exception("Unexpected error")
            return np.zeros(img.shape)
예제 #19
0
    def create_combined_fits_file(cls, name: str,
                                  data: ndarray,
                                  file_type_code: int,
                                  image_type_string: str,
                                  exposure: float,
                                  temperature: float,
                                  filter_name: str,
                                  binning: int,
                                  comment: str):
        """
        Write a new FITS file with the given data and name.
        Create a FITS header in the file by copying the header from a given existing file
        and adding a given comment
        :param name:                File name
        :param data:                2-dimensional array of pixel values, the file contents
        :param file_type_code:      What kind of FITS image file is this (dark, bias, flat, etc.)?
        :param image_type_string:   String for FITS filel "IMGTYP" parameter
        :param exposure:            Exposure time in seconds
        :param temperature:         Temperature in degrees if known, else 0
        :param filter_name:         Name of filter if known
        :param binning:             Binning value of this frame (1, 2, 3, or 4)
        :param comment:             General comment describing this file
        """

        #  Create header
        header = fits.Header()
        header["FILTER"] = filter_name
        header["COMMENT"] = comment
        header["EXPTIME"] = exposure
        header["CCD-TEMP"] = temperature
        header["SET-TEMP"] = temperature
        header["XBINNING"] = binning
        header["YBINNING"] = binning
        header["PICTTYPE"] = file_type_code
        header["IMAGETYP"] = image_type_string

        # Create primary HDU
        data_16_bit = data.round().astype("i2")
        primary_hdu = fits.PrimaryHDU(data_16_bit, header=header)

        # Create HDUL
        hdul = fits.HDUList([primary_hdu])

        # Write to file
        hdul.writeto(name, output_verify="fix", overwrite=True, checksum=True)
예제 #20
0
파일: edges.py 프로젝트: 000o0/triangler
    def compute(img: ndarray, k_size: int = 3) -> ndarray:
        im = img.astype(np.float)
        width, height, c = im.shape
        if c > 1:
            img = 0.2126 * im[:, :, 0] + 0.7152 * im[:, :,
                                                     1] + 0.0722 * im[:, :, 2]
        else:
            img = im

        assert k_size == 3 or k_size == 5

        if k_size == 3:
            kh = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=np.float)
            kv = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], dtype=np.float)
        else:
            kh = np.array(
                [
                    [-1, -2, 0, 2, 1],
                    [-4, -8, 0, 8, 4],
                    [-6, -12, 0, 12, 6],
                    [-4, -8, 0, 8, 4],
                    [-1, -2, 0, 2, 1],
                ],
                dtype=np.float,
            )
            kv = np.array(
                [
                    [1, 4, 6, 4, 1],
                    [2, 8, 12, 8, 2],
                    [0, 0, 0, 0, 0],
                    [-2, -8, -12, -8, -2],
                    [-1, -4, -6, -4, -1],
                ],
                dtype=np.float,
            )

        gx = convolve2d(img, kh, mode="same", boundary="symm")
        gy = convolve2d(img, kv, mode="same", boundary="symm")

        g = np.sqrt(gx * gx + gy * gy)
        g *= 255.0 / np.max(g)

        return g
예제 #21
0
def get_weights(edges_with_grouping_orig: ndarray, groups_members: ndarray,
                affinities: ndarray, left: int, top: int, right: int,
                bottom: int) -> List[float]:
    edges_with_grouping = edges_with_grouping_orig.copy()
    edges_with_grouping[top:bottom, left:right, 1] = -1
    groups_not_in_box = np.unique(edges_with_grouping[:, :, 1])

    def calculate_weight(affs: ndarray, group_id: int):
        def generate_paths(group_len: int, length: int):
            paths: list = [[group_id]]
            for _ in range(length):
                paths = [
                    p + [new_group_id] for p in paths
                    for new_group_id in range(group_len)
                    if new_group_id != p[-1] and
                    affs[new_group_id, p[-1]] > 0.0 and not (new_group_id in p)
                ]
            return list(filter(lambda p: p[-1] in groups_not_in_box, paths))

        if group_id in groups_not_in_box:
            return 0.0
        max_path_length = 10
        max_chained_affinity = 0.0
        for i in range(max_path_length):
            for path in generate_paths(len(groups_members), i):
                path1 = path[0:-1]
                path2 = path[1:]
                adjacent_path = zip(path1, path2)
                affinity_path = map(lambda v12: affinities[v12[0], v12[1]],
                                    adjacent_path)
                affinity_reduced = reduce(lambda a1, a2: a1 * a2,
                                          affinity_path)
                max_chained_affinity = max(affinity_reduced,
                                           max_chained_affinity)
        return 1.0 - max_chained_affinity

    w = [
        calculate_weight(affinities, group_id)
        for group_id in range(len(groups_members))
    ]
    return w
예제 #22
0
파일: Database.py 프로젝트: wlockwood/lits
    def add_encoding(self,
                     encoding: ndarray,
                     associate_id: int,
                     person: bool = False,
                     image: bool = False) -> int:
        """
        Adds an encoding to the database. They must be associated to an existing person or image.
        :param encoding: The encoding's payload
        :param associate_id: The id of the image or person this is associated with
        :param person: Is this associated to a person?
        :param image: Is this associated to an image?
        :return: Id of the newly-created encoding
        """
        # Insert
        sql = "INSERT INTO Encoding (encoding) VALUES (?)"
        encoding_bytes = encoding.tobytes()
        dbresponse = self.connection.execute(sql, [encoding_bytes])
        dbid = dbresponse.lastrowid

        self.get_or_associate_encoding(dbid, associate_id, person, image)
        return dbid
예제 #23
0
    def kernel(self, seq: ndarray, table: ndarray):
        # def max_score(s1, s2):
        #     if s1 >= s2:
        #         return s1
        #     else:
        #         return s2
        #
        def match(b1, b2):
            return b1 + b2 == 3

        table_flattened = table.ravel()
        # scop begin
        for i in range(self.N):
            diag_i = np.arange(0, self.N - i - 1)
            diag_j = np.arange(i + 1, self.N)
            slice_W = slice(i, i + self.N * (self.N - i - 1), self.N + 1)
            slice_center = slice(i + 1, i + 1 + self.N * (self.N - i - 1),
                                 self.N + 1)
            slice_SW = slice(i + self.N, i + self.N * (self.N - i), self.N + 1)
            slice_S = slice(i + 1 + self.N, i + 1 + self.N * (self.N - i),
                            self.N + 1)
            table_flattened[slice_center] = np.maximum(
                table_flattened[slice_center], table_flattened[slice_W])
            table_flattened[slice_center] = np.maximum(
                table_flattened[slice_center], table_flattened[slice_S])
            if i > 0:
                table_flattened[slice_center] = np.maximum(
                    table_flattened[slice_center], table_flattened[slice_SW] +
                    match(seq[0:self.N - 1 - i], seq[i + 1:self.N]))
            else:
                table_flattened[slice_center] = np.maximum(
                    table_flattened[slice_center], table_flattened[slice_SW])
            if i < self.N - 1:
                table_flattened[slice_center] = np.maximum(
                    table_flattened[slice_center],
                    np.max(table[0:self.N - i - 1, i + 1:self.N], axis=0))
예제 #24
0
def denoise_image_rof(img: ndarray,
                      n_iter: int,
                      w_lambda: Union[ndarray, float] = 5) -> ndarray:
    """Primal-dual algorithm for minimization of ROF-functional (TV-L2).
    Fast form of primal-dual algorithm (faster than standard).
    Algotirhm is based on [R1]_.

    Discrete functional:

    - ROF:   min_x( ||_nabla x||_1 + 0.5*lambda*(||x - f||_1)**2 )

    Args:
        img:
            Input image.

        n_iter:
            Number of iterations

        w_lambda:
            Weight factor of data term. Pixel-wise weight is possible.

    Returns:
        The filtered image of the same shape as the input image.

    References:
        .. [R1] Chambolle, Antonin; Pock, Thomas (2011): A First-Order
           Primal-Dual Algorithm for Convex Problems with Applications
           to Imaging. In: Journal of Mathematical Imaging and Vision 40 (1)
    """

    u = img.copy()
    y = _nabla(u)

    L2 = 8
    tau = 0.02
    sigma = 1.0 / (L2 * tau)
    gamma = 0.35 * w_lambda

    for i in range(n_iter):

        # Calculate gradient
        u_grad = _nabla(u)

        # Optimize dual variable ( prox_f )
        y = y + sigma * u_grad

        # Projection
        y = _prox_tv(y)

        # Optimize primal variable ( prox_g )
        u_new = u - tau * _nablaT(y)

        # l2-norm (ROF denoising)
        u_new = _prox_l2(u_new, img, w_lambda * tau)

        # Optimize step-size (faster convergence)
        theta = 1 / np.sqrt(1 + 2 * gamma * tau)
        tau = theta * tau
        sigma = sigma / theta

        # Extrapolate
        u = u_new + theta * (u_new - u)

        # Break if max accuracy reached
        # if (np.abs(u[:]-u_new[:])).sum() < tol:
        #     print(i)
        #     break

    return u
예제 #25
0
def _display_bbs(img: ndarray, bbs: List[Tuple[Point, Size2D]]) -> ndarray:
    _img = img.copy()
    for bb in bbs:
        _img = draw_bbox_on_image(_img, bb, color=(0, 255, 0))
    return _img
예제 #26
0
 def _blank_image(image: ndarray) -> ndarray:
     image = np.zeros((image.shape[0], image.shape[1]), dtype='uint8')
     image.fill(255)
     return image
예제 #27
0
def conv2d(data_in: ndarray, kernel: ndarray, stride: int = 1):
    """
    Perform a 2D convolution over a batch of tensors. This is equivalent to

     output[b, i, j, k] =
         sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] *
                         filter[di, dj, q, k]

    :param data_in: Input data tensor with shape [batch, height, width, channels_in]
    :param kernel: Convolution kernel tensor with shape [kernel_height, kernel_width, channels_in, channels_out]
    :param stride: Integer for the step width
    :return: Tensor with shape [batch, height/stride, width/stride, channels_out]
    """

    # Obtain shapes
    fh, fw, kin_ch, kout_ch = kernel.shape
    batch, in_h, in_w, in_ch = data_in.shape

    if kin_ch != in_ch:
        raise ValueError("Input channel mismatch")

    # Check if the filter has an uneven width
    assert (1 == fh % 2)
    assert (1 == fw % 2)

    # Find the midpoint of the filter. This only works for odd filter sizes
    fh2 = int((fh - 1) / 2)
    fw2 = int((fw - 1) / 2)

    # Given an input tensor of shape [batch, in_height, in_width, in_channels] and a filter / kernel tensor of
    # shape [filter_height, filter_width, in_channels, out_channels], this op performs the following:
    #
    # 1) Flattens the filter to a 2-D matrix with shape [filter_height * filter_width * in_channels,
    # output_channels].
    #
    # 2) Extracts image patches from the input tensor to form a virtual tensor of shape [batch,
    # out_height, out_width, filter_height * filter_width * in_channels].
    #
    # 3) For each patch, right-multiplies the
    # filter matrix and the image patch vector
    if kernel.dtype.kind in 'ui':  # check if datatype is unsigned or integer
        out = np.zeros(shape=[batch, in_h, in_w, kout_ch], dtype=np.int32)
    else:
        out = np.zeros(shape=[batch, in_h, in_w, kout_ch], dtype=data_in.dtype)
    # pad input
    in_padded = np.pad(data_in, ((0, 0), (fh2, fh2), (fw2, fw2), (0, 0)),
                       'constant',
                       constant_values=(0, 0))
    # in_padded = np.pad(data_in, ((0, 0), (30, 30), (30, 30), (0, 0)), 'constant', constant_values=(0, 0))
    # img = np.squeeze(in_padded)
    # fig, ax = plt.subplots()
    # _im = ax.imshow(img, cmap='gray')
    # fig.colorbar(_im)
    # plt.show()

    # kflat = np.reshape(kernel, newshape=(-1, kout_ch))
    # vout = np.zeros(shape=(batch, in_h, in_w, fh * fw * in_ch))  # create virtual out
    #
    # for b in range(batch):
    #     for i in range(in_h):
    #         for j in range(in_w):
    #             vout[b, i, j, :] = np.reshape(in_padded[b, i:i+fh, j:j+fw, :], newshape=(-1))
    #
    # out = np.dot(vout, kflat)

    # output[b, i, j, k] =
    #     sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] *
    #                     filter[di, dj, q, k]

    for b in range(batch):
        for k in range(kout_ch):
            # k = kernel[:, :, q, k]  # 2d kernel

            # Perform convolution
            i_out, j_out = 0, 0
            for i in range(0, in_h, stride):
                for j in range(0, in_w, stride):
                    patch = in_padded[b, i:i + fh,
                                      j:j + fw, :]  # 3d tensor 3x3x16

                    if kernel.dtype.kind in 'ui':  # check if datatype is unsigned or integer
                        patch16 = patch.astype(np.int16)
                        kernel16 = kernel.astype(np.int16)
                        temp = patch16 * kernel16[:, :, :, k]
                        temp = temp.flatten().astype(np.int64)
                        # patch_sum = np.sum(patch * kernel[:, :, :, k], axis=(0, 1, 2))  # sum along all axis
                        # min_value = np.iinfo(kernel.dtype).min
                        # max_value = np.iinfo(kernel.dtype).max
                        patch_sum = np.sum(temp)
                        out[b, i_out, j_out, k] = patch_sum
                    else:
                        # patch_sum is always int64
                        patch_sum = np.sum(patch * kernel[:, :, :, k],
                                           axis=(0, 1,
                                                 2))  # sum along all axis
                        out[b, i_out, j_out, k] = patch_sum
                    j_out += 1
                j_out = 0
                i_out += 1

    return out
예제 #28
0
def calculate_metrics(confusion_matrix: ndarray) -> tuple:
    tn, fp, fn, tp = confusion_matrix.ravel()
    accuracy = (tp + tn) / sum([tn, fp, fn, tp])
    recall = tp / (tp + fn)
    precision = tp / (tp + fp)
    return accuracy, recall, precision
예제 #29
0
def right_generalized_inverse_jacobian(jacobian: ndarray) -> ndarray:
    jacobian_t = jacobian.transpose()
    try:
        return jacobian_t @ inv(jacobian @ jacobian_t)
    except TypeError:
        raise ValueError(jacobian @ jacobian_t)
예제 #30
0
def get_gradients(im: ndarray,
                  method='sobel',
                  **kwargs) -> Tuple[ndarray, ndarray]:
    """Get the gradients of a 2D-image using different methods.

    Args:
        im: Input image of shape (x, y). Only monochromatic images are supported here.
        method: Used method for gradient calculation. Possible values are:
                    * 'scharr': Scharr filter.
                    * 'sobel': Sobel filter.
                    * 'dog': Difference of Gaussians.
                    * 'gradient': Numpy's ``gradient()`` method

    Returns:
        Tuple (gx, gy).
        Gradient gx, gy in x- and y-direction, respectively.

    """
    im = im.squeeze()

    if im.ndim != 2:
        raise ValueError(
            "Gradient calculation only works on 2D images right now. "
            "For multi-dimensional arrays, use numpy's gradient() instead.")

    x, y = im.shape

    # Get image gradients
    param_list = ["scharr", "sobel", "dog", "gradient"]
    method = method.lower()

    if method not in param_list:
        raise ValueError(
            f"Specified method '{method}' is not one of the recognized "
            f"methods: {param_list}")

    if method == 'scharr':
        h = np.array([[3, 10, 3], [0, 0, 0], [-3, -10, -3]])
        grad_x = convolve(im, h.T)
        grad_y = convolve(im, h)

    elif method == 'sobel':
        h = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]])
        grad_x = convolve(im, h.T)
        grad_y = convolve(im, h)

    elif method == 'dog':
        if not 'sigma' in kwargs:
            sigma_1 = min(x, y) / 800
        else:
            sigma_1 = kwargs['sigma']

        sigma_2 = 1.6 * sigma_1
        grad_x = gaussian_filter(im, [sigma_1, 0]) - gaussian_filter(
            im, [sigma_2, 0])
        grad_y = gaussian_filter(im, [0, sigma_1]) - gaussian_filter(
            im, [0, sigma_2])

    elif method == 'gradient':
        grad_y, grad_x = np.gradient(im)  # central differences

    return grad_x, grad_y