Browse Source

Added experiment "AreSameImagesReferenceOneExtract"

rigwild 1 year ago
parent
commit
3dc13239fa

+ 1 - 1
cleanExtracts.js

@@ -61,4 +61,4 @@ if (argv.includes('--execute')) {
   setup(process.env.IMAGES_PATH, false, true)
 }
 
-module.exports = setup
+module.exports = { setup, extractsRemoverServiceLogger: fileLogger }

+ 17 - 12
experimentConfig.default.js

@@ -1,13 +1,7 @@
 export const mixins = {
   ExperimentBase: {
-    defaultConfig: {
-      lockConfig: true
-    },
-    scenesConfig: {
-      // bathroom: {
-      //   lockConfig: true
-      // }
-    }
+    defaultConfig: {},
+    scenesConfig: {}
   },
 
   ExperimentBaseAreSameImages: {
@@ -23,7 +17,8 @@ export const mixins = {
 
   ExperimentBaseExtracts: {
     defaultConfig: {
-      showHoverBorder: false,
+      lockConfig: false,
+      showHoverBorder: true,
       extractConfig: {
         x: 4,
         y: 4
@@ -31,6 +26,7 @@ export const mixins = {
     },
     scenesConfig: {
       // bathroom: {
+      //   lockConfig: false,
       //   showHoverBorder: false,
       //   extractConfig: {
       //     x: 4,
@@ -44,7 +40,7 @@ export const mixins = {
 
 export const experiments = {
   MatchExtractsWithReference: {
-    mixin: mixins.ExperimentBaseExtracts,
+    mixins: [mixins.ExperimentBaseExtracts],
     defaultConfig: {},
     scenesConfig: {},
     availableScenes: {
@@ -58,7 +54,7 @@ export const experiments = {
     }
   },
   AreSameImagesRandom: {
-    mixin: mixins.ExperimentBaseAreSameImages,
+    mixins: [mixins.ExperimentBaseAreSameImages],
     defaultConfig: {},
     scenesConfig: {},
     availableScenes: {
@@ -67,7 +63,16 @@ export const experiments = {
     }
   },
   AreSameImagesReference: {
-    mixin: mixins.ExperimentBaseAreSameImages,
+    mixins: [mixins.ExperimentBaseAreSameImages],
+    defaultConfig: {},
+    scenesConfig: {},
+    availableScenes: {
+      whitelist: null,
+      blacklist: null
+    }
+  },
+  AreSameImagesReferenceOneExtract: {
+    mixins: [mixins.ExperimentBaseAreSameImages, mixins.ExperimentBaseExtracts],
     defaultConfig: {},
     scenesConfig: {},
     availableScenes: {

+ 2 - 2
index.js

@@ -3,7 +3,7 @@
 import { CronJob } from 'cron'
 
 import server from './server'
-import cleanExtracts from './cleanExtracts'
+import { setup as cleanExtracts, extractsRemoverServiceLogger } from './cleanExtracts'
 import { imagesPath, deleteExtractsCronTime } from './config'
 
 const argv = process.argv.slice(2)
@@ -11,7 +11,7 @@ const argv = process.argv.slice(2)
 // Start the extracts remover service
 if (!argv.includes('--no-delete')) { /* eslint no-new: 0 */
   new CronJob(deleteExtractsCronTime, () => cleanExtracts(imagesPath, false, true), null, true, null, null, false)
-  console.log('Started the extracts remover service.')
+  extractsRemoverServiceLogger.info('Started the extracts remover service.')
 }
 
 // Start the server

+ 38 - 0
src/components/ExperimentsComponents/ExtractsToImage.vue

@@ -0,0 +1,38 @@
+<template>
+  <div>
+    <template v-for="i in extractConfig.y">
+      <v-layout row wrap :key="`row-${i}`">
+        <v-flex
+          v-for="(anExtract, index) in extractsSliced(i)"
+          :key="`extract-${i}-${extractConfig.x}-${extractConfig.y}-${index}-${anExtract.quality}`"
+          class="pa-0"
+        >
+          <v-card flat tile class="d-flex height100">
+            <v-img :src="anExtract" />
+          </v-card>
+        </v-flex>
+      </v-layout>
+    </template>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'ExtractsToImage',
+  props: {
+    extractConfig: {
+      type: Object,
+      required: true
+    },
+    extracts: {
+      type: Array,
+      required: true
+    }
+  },
+  computed: {
+    extractsSliced() {
+      return vForIndex => this.extracts.slice(this.extractConfig.x * (vForIndex - 1), (this.extractConfig.x * vForIndex))
+    }
+  }
+}
+</script>

+ 1 - 3
src/mixins/ExperimentBase.vue

@@ -24,9 +24,7 @@ export default {
 
       loadingMessage: null,
       loadingErrorMessage: null,
-      qualities: null,
-
-      lockConfig: null
+      qualities: null
     }
   },
   computed: {

+ 16 - 13
src/mixins/ExperimentBaseAreSameImages.vue

@@ -19,8 +19,8 @@ export default {
       maxTestCount: null,
       testCount: 1,
 
-      leftImage: { link: null, quality: null },
-      rightImage: { link: null, quality: null }
+      image1: null,
+      image2: null
     }
   },
   computed: {
@@ -35,11 +35,11 @@ export default {
     // Get images links for a test
     async getTest(leftQuality, rightQuality) {
       const res = await Promise.all([this.getImage(leftQuality), this.getImage(rightQuality)])
-      const [leftImage, rightImage] = res.map(x => {
+      const [image1, image2] = res.map(x => {
         x.link = `${this.getHostURI}${x.link}`
         return x
       })
-      return { leftImage, rightImage }
+      return { image1, image2 }
     },
 
     // Get a test with random qualities
@@ -58,6 +58,7 @@ export default {
       const randomQuality = this.qualities[rand(0, this.qualities.length - 1)]
 
       const res = [this.qualities[this.qualities.length - 1], randomQuality]
+      this.referenceImagePosition = isReferenceLeft ? 'left' : 'right'
       const table = isReferenceLeft ? res : res.reverse()
       return this.getTest(table[0], table[1])
     },
@@ -65,26 +66,28 @@ export default {
     /** An action was triggered, load a new test and save progression
      * @param {Boolean} areTheSame Are the images the same
      * @param {Function} getTestFn Function to be called to get the next tests
+     * @param {Function} additionalData Object to concat to log
      * @returns {void}
      */
-    async areTheSameAction(areTheSame, getTestFn) {
+    async areTheSameAction(areTheSame, getTestFn, additionalData) {
       this.loadingMessage = 'Loading new test...'
       this.loadingErrorMessage = null
       try {
         this.testCount++
 
-        const obj = {
-          leftImage: this.leftImage,
-          rightImage: this.rightImage,
+        const obj = Object.assign({
+          image1: this.image1,
+          image2: this.image2,
           areTheSame,
           experimentName: this.experimentName,
-          sceneName: this.sceneName
-        }
+          sceneName: this.sceneName,
+          referenceImagePosition: this.referenceImagePosition || undefined
+        }, additionalData || {})
         this.sendMessage({ msgId: experimentMsgId.DATA, msg: obj })
 
-        const { leftImage, rightImage } = await getTestFn()
-        this.leftImage = leftImage
-        this.rightImage = rightImage
+        const { image1, image2 } = await getTestFn()
+        this.image1 = image1
+        this.image2 = image2
 
         // Experiment end
         if (this.testCount > this.maxTestCount) return this.finishExperiment()

+ 18 - 12
src/mixins/ExperimentBaseExtracts.vue

@@ -24,7 +24,8 @@ export default {
       extracts: [],
       extractsInfos: null,
 
-      showHoverBorder: null
+      showHoverBorder: null,
+      lockConfig: null
     }
   },
   computed: {
@@ -46,6 +47,19 @@ export default {
       return data
     },
 
+    // Convert a simple API extracts object to get more informations
+    getExtractFullObject(extractsApiObj) {
+      return extractsApiObj.extracts.map((url, i) => ({
+        link: this.getHostURI + url,
+        quality: extractsApiObj.info.image.quality,
+        zone: i + 1,
+        index: i,
+        nextQuality: findNearestUpper(extractsApiObj.info.image.quality, this.qualities),
+        precQuality: findNearestLower(extractsApiObj.info.image.quality, this.qualities),
+        loading: false
+      }))
+    },
+
     // Config was updated, load extracts and save progression
     async setExtractConfig(config, configuratorRef) {
       if (!config) return
@@ -55,18 +69,10 @@ export default {
       try {
         this.extractConfig.x = config.x
         this.extractConfig.y = config.y
-        const data = await this.getExtracts()
-        const hostURI = this.getHostURI
+        this.extractConfig.quality = config.quality
+        const data = await this.getExtracts(config.quality || undefined)
         this.extractsInfos = data.info
-        this.extracts = data.extracts.map((url, i) => ({
-          link: hostURI + url,
-          quality: data.info.image.quality,
-          zone: i + 1,
-          index: i,
-          nextQuality: findNearestUpper(data.info.image.quality, this.qualities),
-          precQuality: findNearestLower(data.info.image.quality, this.qualities),
-          loading: false
-        }))
+        this.extracts = this.getExtractFullObject(data)
 
         // If there is a configurator, retract it
         if (configuratorRef) configuratorRef.setVisibility(false)

+ 9 - 0
src/router/experiments.js

@@ -25,5 +25,14 @@ export default [
     meta: {
       fullName: 'Are images the same ? (One is reference image, the other is random quality)'
     }
+  },
+  {
+    path: '/experiments/AreSameImagesReferenceOneExtract/:sceneName',
+    name: 'AreSameImagesReferenceOneExtract',
+    component: () => import('@/views/Experiments/AreSameImagesReferenceOneExtract'),
+    props: true,
+    meta: {
+      fullName: 'Are images the same ? (Both are reference images but one contains a random quality extract)'
+    }
   }
 ]

+ 173 - 0
src/views/Experiments/AreSameImagesReferenceOneExtract.vue

@@ -0,0 +1,173 @@
+<template>
+  <div>
+    <v-container grid-list-md text-xs-center fluid>
+      <v-layout row wrap>
+        <v-flex xs12>
+          <v-layout justify-start>
+            <v-btn flat exact :to="`/experiments/${experimentName}`">
+              <v-icon left>arrow_back</v-icon>
+              Back to scene selection
+            </v-btn>
+          </v-layout>
+
+          <h2>Experiment "{{ $route.meta.fullName }}"</h2>
+          <h3>{{ sceneName }}</h3>
+        </v-flex>
+        <!-- Loading screen -->
+        <loader v-if="loadingMessage" :message="loadingMessage" />
+        <!--/ Loading screen -->
+
+        <!-- Experiment -->
+        <template v-else-if="!loadingErrorMessage && image1 && image2">
+          <v-flex xs12 sm6>
+            <v-card dark color="primary">
+              <v-card-text class="px-0">Image 1</v-card-text>
+
+              <v-container v-if="imageOneExtractPosition === 'left'" class="pa-1">
+                <ExtractsToImage :extracts="image1" :extract-config="extractConfig" />
+              </v-container>
+              <v-img v-else :src="image2.link" @load="scrollToChoiceButtons">
+                <template v-slot:placeholder>
+                  <v-layout fill-height align-center justify-center ma-0>
+                    <v-progress-circular indeterminate color="grey lighten-5" />
+                  </v-layout>
+                </template>
+              </v-img>
+            </v-card>
+          </v-flex>
+          <v-flex xs12 sm6>
+            <v-card dark color="primary">
+              <v-card-text>Image 2</v-card-text>
+              <v-container v-if="imageOneExtractPosition === 'right'" class="pa-1">
+                <ExtractsToImage :extracts="image1" :extract-config="extractConfig" />
+              </v-container>
+              <v-img v-else :src="image2.link" @load="scrollToChoiceButtons">
+                <template v-slot:placeholder>
+                  <v-layout fill-height align-center justify-center ma-0>
+                    <v-progress-circular indeterminate color="grey lighten-5" />
+                  </v-layout>
+                </template>
+              </v-img>
+            </v-card>
+          </v-flex>
+
+
+          <!-- Experiment validation button -->
+          <v-layout justify-center align-content-center>
+            <div id="choice">
+              <v-container grid-list-md text-xs-center fluid>
+                <h2>Test {{ testCount }} / {{ maxTestCount }}</h2>
+                <v-layout row wrap>
+                  <v-flex sm6 xs12>
+                    <v-btn @click="areTheSameActionLocal(false)" color="error" large>Images are NOT the same</v-btn>
+                  </v-flex>
+                  <v-flex sm6 xs12>
+                    <v-btn @click="areTheSameActionLocal(true)" color="success" large>Images are the same</v-btn>
+                  </v-flex>
+                </v-layout>
+              </v-container>
+            </div>
+          </v-layout>
+          <!--/ Experiment validation button -->
+        </template>
+        <!--/ Experiment -->
+      </v-layout>
+    </v-container>
+  </div>
+</template>
+
+<script>
+import ExperimentBaseExtracts from '@/mixins/ExperimentBaseExtracts'
+import ExperimentBaseAreSameImages from '@/mixins/ExperimentBaseAreSameImages'
+import Loader from '@/components/Loader'
+import ExtractsToImage from '@/components/ExperimentsComponents/ExtractsToImage'
+import { rand } from '@/functions'
+
+export default {
+  name: 'AreSameImagesReferenceOneExtract',
+  components: {
+    Loader,
+    ExtractsToImage
+  },
+  mixins: [
+    ExperimentBaseExtracts,
+    ExperimentBaseAreSameImages
+  ],
+
+  data() {
+    return {
+      experimentName: 'AreSameImagesReferenceOneExtract',
+
+      imageOneExtractPosition: null,
+      randomZoneIndex: null,
+      randomZoneQuality: null
+    }
+  },
+
+  async mounted() {
+    // Load config for this scene to local state
+    this.loadConfig()
+
+    // Load progress from store into local state
+    this.loadProgress()
+
+    // Load scene data from the API
+    await this.getQualitiesList()
+
+    // Load a test if not already one loaded
+    if (!this.image1 || !this.image2) {
+      const { image1, image2 } = await this.getReferenceOneExtractTest()
+      this.image1 = image1
+      this.image2 = image2
+    }
+
+    this.saveProgress()
+  },
+
+  methods: {
+    // Get a test with one random quality and a reference
+    async getReferenceOneExtractTest() {
+      // Randomly choose a quality for the extract
+      const randomQuality = this.qualities[rand(0, this.qualities.length - 1)]
+
+      const maxQuality = this.qualities[this.qualities.length - 1]
+
+      // Get the reference image, extracts of reference image and random quality extracts
+      const [maxExtracts, randomExtracts, maxImage] = await Promise.all([
+        this.getExtracts('max'),
+        this.getExtracts(randomQuality),
+        this.getImage(maxQuality)
+      ])
+
+      // Select which zone is the random extract (-1 to get array index)
+      const randomZoneIndex = rand(0, maxExtracts.extracts.length - 1)
+      // Apply the random quality extract
+      maxExtracts.extracts[randomZoneIndex] = randomExtracts.extracts[randomZoneIndex]
+
+      // Fix uris
+      const referenceWithOneExtract = maxExtracts.extracts.map(url => this.getHostURI + url)
+      maxImage.link = this.getHostURI + maxImage.link
+
+      // Backup test data
+      this.randomZoneIndex = randomZoneIndex
+      this.randomZoneQuality = randomQuality
+      this.imageOneExtractPosition = rand(0, 1) === 0 ? 'left' : 'right'
+
+      return {
+        image1: referenceWithOneExtract,
+        image2: maxImage
+      }
+    },
+
+    areTheSameActionLocal(areTheSame) {
+      const additionalData = {
+        imageOneExtractPosition: this.imageOneExtractPosition,
+        randomZoneIndex: this.randomZoneIndex,
+        randomZone: this.randomZoneIndex + 1,
+        randomZoneQuality: this.randomZoneQuality
+      }
+      this.areTheSameAction(areTheSame, this.getReferenceOneExtractTest, additionalData)
+    }
+  }
+}
+</script>