test_chemometricMethods.py 5.99 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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
import unittest
import cv2
import numpy as np
import sys
import matplotlib.pyplot as plt

sys.path.append("C://Users//xbrjos//Desktop//Python")
from gepard.analysis import particleAndMeasurement as pm
from gepard.analysis.particleContainer import ParticleContainer
from gepard import dataset

import chemometricMethods as cmeth


class TestFeatureExtractor(unittest.TestCase):
    def setUp(self) -> None:
        self.extractor: cmeth.FeatureExtractor = cmeth.FeatureExtractor(None)

    def test_get_contour_moments(self):
        imgs = []
        imgA: np.ndarray = np.zeros((200, 200), dtype=np.uint8)
        cv2.putText(imgA, 'A', (25, 175), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=7, color=1, thickness=5)
        imgs.append(imgA.copy())

        imgA_translated: np.ndarray = np.zeros((200, 200), dtype=np.uint8)
        cv2.putText(imgA_translated, 'A', (10, 180), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=7, color=1, thickness=5)
        imgs.append(imgA_translated)
        imgs.append(cv2.rotate(imgA, cv2.ROTATE_90_CLOCKWISE))
        imgs.append(cv2.rotate(imgA, cv2.ROTATE_180))
        imgs.append(cv2.resize(imgA, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR))
        imgs.append(cv2.resize(imgA, None, fx=1.5, fy=1.5, interpolation=cv2.INTER_LINEAR))

        moments: np.ndarray = np.zeros((7, len(imgs)))  # we prepare an empty array for 7 hu moments per image
        for i, img in enumerate(imgs):
            contours, hierarchy = cv2.findContours(img, 1, 2)
            particle: pm.Particle = pm.Particle()
            particle.contour = contours[0]
            self.extractor.particle = particle
            hu: np.ndarray = self.extractor._get_log_hu_moments()
            moments[:, i] = hu

        # The first six hu moments are supposed to be invariant to scale, rotation and translation
        # Small errors can occur, as the test image is of low resolution...
        for i in range(6):
            diff: np.ndarray = moments[i, :] - np.mean(moments[i, :])
            self.assertFalse(np.any(diff > 0.1))


class TestKennardStone(unittest.TestCase):
    def setUp(self) -> None:
        self.kennardStone: cmeth.KennardStone = cmeth.KennardStone(np.array([]), 0.1)

    def test_get_sampled_indices(self):
Josef Brandt's avatar
Josef Brandt committed
56
        numDataSets: int = 1000
57 58 59 60 61 62 63 64 65
        self.kennardStone.data = np.random.rand(numDataSets, 2)
        self.kennardStone.fraction = 0.1
        selectedIndices = self.kennardStone.get_sampled_indices()
        self.assertEqual(len(selectedIndices), numDataSets*self.kennardStone.fraction)
        self.assertEqual(len(np.unique(selectedIndices)), numDataSets*self.kennardStone.fraction)

        self.kennardStone.fraction = 0.1
        numDataSets = 2
        self.kennardStone.data = np.random.rand(numDataSets, 2)
66 67 68 69 70 71 72 73 74
        selectedIndices = self.kennardStone.get_sampled_indices()
        self.assertEqual(len(selectedIndices), 1)

        self.kennardStone.fraction = 0.5
        numDataSets = 2
        self.kennardStone.data = np.random.rand(numDataSets, 2)
        selectedIndices = self.kennardStone.get_sampled_indices()
        self.assertEqual(len(selectedIndices), numDataSets * self.kennardStone.fraction)
        self.assertEqual(len(np.unique(selectedIndices)), numDataSets * self.kennardStone.fraction)
75 76 77

        numDataSets = 20
        self.kennardStone.data = np.random.rand(numDataSets, 2)
78
        self.kennardStone.fraction = 0.1
79 80 81
        selectedIndices = self.kennardStone.get_sampled_indices()
        self.assertEqual(len(selectedIndices), 2)
        self.assertEqual(len(np.unique(selectedIndices)), 2)
82 83 84

    def test_get_start_indices(self):
        points: list = [[0, 0], [10, 10]]
85
        for _ in range(100):
86
            points.append([np.random.rand()*5 + 2.5, np.random.rand()*5 + 2.5])
87

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
        self.kennardStone.data = np.array(points)
        startIndices: list = self.kennardStone._get_start_indices()
        self.assertEqual(startIndices, [0, 1])

        points.append([20, 20])
        self.kennardStone.data = np.array(points)
        startIndices = self.kennardStone._get_start_indices()
        self.assertEqual(startIndices, [0, len(points)-1])

        points.insert(4, [-10, -10])
        self.kennardStone.data = np.array(points)
        startIndices = self.kennardStone._get_start_indices()
        self.assertEqual(startIndices, [4, len(points) - 1])


class TestChemometricSubsampling(unittest.TestCase):
    def setUp(self) -> None:
        particleContainer: ParticleContainer = ParticleContainer(None)
        numParticles: int = 5
        particleContainer.initializeParticles(numParticles)
        img: np.ndarray = np.zeros((20, 20), dtype=np.uint8)
        cv2.putText(img, 'A', (2, 2), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=1, color=1, thickness=2)
        contours, hierarchy = cv2.findContours(img, 1, 2)
        particleContainer.setParticleContours([contours[0] for i in range(numParticles)])
        self.chemSubs: cmeth.ChemometricSubsampling = cmeth.ChemometricSubsampling(particleContainer, desiredFraction=0.1)

115 116 117 118 119 120 121
    # def test_get_particle_featurematrix(self):
    #     features: np.ndarray = self.chemSubs._get_particle_featurematrix()
    #     self.assertEqual(features.shape, (7, 5))
    #     for i in range(6):
    #         diff: np.ndarray = features[i, :] - np.mean(features[i, :])
    #         self.assertFalse(np.any(diff > 0.1))

122 123 124 125 126 127 128 129 130 131
    # def test_pca(self):
    #     fname = r'C:\Users\xbrjos\Desktop\temp MP\190326_MCII_WWTP_SB_50_1\190326_MCII_WWTP_SB_50_1.pkl'
    #     fname = r'C:\Users\xbrjos\Desktop\temp MP\190313_Soil_5_A_50_5_1_50_1\190313_Soil_5_A_50_5_1_50_1.pkl'
    #     fname = r'C:\Users\xbrjos\Desktop\temp MP\190201_BSB_Stroomi_ds2_R1_R2_50\190201_BSB_Stroomi_ds2_R1_R2_50.pkl'
    #     dset: dataset.Dataset = dataset.loadData(fname)
    #     self.chemSubs.particleContainer = dset.particleContainer
    #     princComp: np.ndarray = cmeth.get_pca(self.chemSubs._get_particle_featurematrix())
    #     plt.scatter(princComp[:, 0], princComp[:, 1])
    #     plt.title(dset.name)
    #     plt.show()
Josef Brandt's avatar
Josef Brandt committed
132
    #