Extract module imageprocessing (#76)
This commit is contained in:
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="21" />
|
<bytecodeTargetLevel target="11" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@@ -11,6 +11,7 @@
|
|||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
<option value="$PROJECT_DIR$/app" />
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
<option value="$PROJECT_DIR$/imageprocessing" />
|
||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
</GradleProjectSettings>
|
</GradleProjectSettings>
|
||||||
|
|||||||
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="2.1.0" />
|
<option name="version" value="2.2.21" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|||||||
@@ -88,8 +88,10 @@ android {
|
|||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
targetCompatibility = JavaVersion.VERSION_11
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlin {
|
||||||
jvmTarget = "11"
|
compilerOptions {
|
||||||
|
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose = true
|
compose = true
|
||||||
@@ -101,6 +103,10 @@ apply(from = "download-tflite.gradle.kts")
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
|
implementation(project(":imageprocessing")) {
|
||||||
|
exclude(group = "org.openpnp", module = "opencv")
|
||||||
|
}
|
||||||
|
|
||||||
implementation(libs.androidx.core.ktx)
|
implementation(libs.androidx.core.ktx)
|
||||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||||
implementation(libs.androidx.lifecycle.runtime.compose)
|
implementation(libs.androidx.lifecycle.runtime.compose)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import androidx.test.core.app.ApplicationProvider
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.fairscan.imageprocessing.scaledTo
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.fail
|
import org.junit.Assert.fail
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import kotlinx.coroutines.sync.Mutex
|
|||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.fairscan.app.data.Logger
|
import org.fairscan.app.data.Logger
|
||||||
|
import org.fairscan.imageprocessing.Mask
|
||||||
import org.opencv.core.CvType
|
import org.opencv.core.CvType
|
||||||
import org.opencv.core.Mat
|
import org.opencv.core.Mat
|
||||||
import org.tensorflow.lite.DataType
|
import org.tensorflow.lite.DataType
|
||||||
@@ -132,7 +133,11 @@ class ImageSegmentationService(private val context: Context, private val logger:
|
|||||||
return maskFloats
|
return maskFloats
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Segmentation(private val probmap: FloatArray, val width: Int, val height: Int) {
|
data class Segmentation(
|
||||||
|
private val probmap: FloatArray,
|
||||||
|
override val width: Int,
|
||||||
|
override val height: Int
|
||||||
|
): Mask {
|
||||||
fun get(x: Int, y: Int): Float = probmap[y * width + x]
|
fun get(x: Int, y: Int): Float = probmap[y * width + x]
|
||||||
fun toBinaryMask(): Bitmap {
|
fun toBinaryMask(): Bitmap {
|
||||||
val bmp = createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
val bmp = createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||||
@@ -144,7 +149,8 @@ class ImageSegmentationService(private val context: Context, private val logger:
|
|||||||
bmp.setPixels(pixels, 0, width, 0, 0, width, height)
|
bmp.setPixels(pixels, 0, width, 0, 0, width, height)
|
||||||
return bmp
|
return bmp
|
||||||
}
|
}
|
||||||
fun toMat(): Mat {
|
|
||||||
|
override fun toMat(): Mat {
|
||||||
val mat = Mat(height, width, CvType.CV_32FC1)
|
val mat = Mat(height, width, CvType.CV_32FC1)
|
||||||
mat.put(0, 0, probmap)
|
mat.put(0, 0, probmap)
|
||||||
return mat
|
return mat
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ import androidx.core.graphics.scale
|
|||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
import org.fairscan.app.domain.Point
|
import org.fairscan.imageprocessing.Point
|
||||||
import org.fairscan.app.domain.scaledTo
|
import org.fairscan.imageprocessing.scaledTo
|
||||||
import org.fairscan.app.ui.components.CameraPermissionState
|
import org.fairscan.app.ui.components.CameraPermissionState
|
||||||
import java.util.concurrent.ExecutorService
|
import java.util.concurrent.ExecutorService
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ package org.fairscan.app.ui.screens.camera
|
|||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import org.fairscan.app.domain.Quad
|
import org.fairscan.imageprocessing.Quad
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class LiveAnalysisState(
|
data class LiveAnalysisState(
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package org.fairscan.app.ui.screens.camera
|
|||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.camera.core.ImageProxy
|
import androidx.camera.core.ImageProxy
|
||||||
|
import androidx.core.graphics.createBitmap
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -30,9 +31,12 @@ import kotlinx.coroutines.flow.map
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.fairscan.app.AppContainer
|
import org.fairscan.app.AppContainer
|
||||||
import org.fairscan.app.domain.detectDocumentQuad
|
import org.fairscan.imageprocessing.Quad
|
||||||
import org.fairscan.app.domain.extractDocument
|
import org.fairscan.imageprocessing.detectDocumentQuad
|
||||||
import org.fairscan.app.domain.scaledTo
|
import org.fairscan.imageprocessing.extractDocument
|
||||||
|
import org.fairscan.imageprocessing.scaledTo
|
||||||
|
import org.opencv.android.Utils
|
||||||
|
import org.opencv.core.Mat
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
sealed interface CameraEvent {
|
sealed interface CameraEvent {
|
||||||
@@ -143,7 +147,7 @@ class CameraViewModel(appContainer: AppContainer): ViewModel() {
|
|||||||
}
|
}
|
||||||
if (quad != null) {
|
if (quad != null) {
|
||||||
val resizedQuad = quad.scaledTo(mask.width, mask.height, bitmap.width, bitmap.height)
|
val resizedQuad = quad.scaledTo(mask.width, mask.height, bitmap.width, bitmap.height)
|
||||||
corrected = extractDocument(bitmap, resizedQuad, imageProxy.imageInfo.rotationDegrees)
|
corrected = extractDocumentFromBitmap(bitmap, resizedQuad, imageProxy.imageInfo.rotationDegrees)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@withContext corrected
|
return@withContext corrected
|
||||||
@@ -179,3 +183,15 @@ sealed class CaptureState {
|
|||||||
val processed: Bitmap
|
val processed: Bitmap
|
||||||
) : CaptureState()
|
) : CaptureState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun extractDocumentFromBitmap(originalBitmap: Bitmap, quad: Quad, rotationDegrees: Int): Bitmap {
|
||||||
|
val inputMat = Mat()
|
||||||
|
Utils.bitmapToMat(originalBitmap, inputMat)
|
||||||
|
return toBitmap(extractDocument(inputMat, quad, rotationDegrees))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toBitmap(mat: Mat): Bitmap {
|
||||||
|
val outputBitmap = createBitmap(mat.cols(), mat.rows())
|
||||||
|
Utils.matToBitmap(mat, outputBitmap)
|
||||||
|
return outputBitmap
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ plugins {
|
|||||||
alias(libs.plugins.kotlin.compose) apply false
|
alias(libs.plugins.kotlin.compose) apply false
|
||||||
alias(libs.plugins.aboutLibrariesAndroid) apply false
|
alias(libs.plugins.aboutLibrariesAndroid) apply false
|
||||||
alias(libs.plugins.license)
|
alias(libs.plugins.license)
|
||||||
|
alias(libs.plugins.jetbrains.kotlin.jvm) apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
license {
|
license {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ datastore = "1.2.0"
|
|||||||
documentfile = "1.1.0"
|
documentfile = "1.1.0"
|
||||||
litert = "1.4.1"
|
litert = "1.4.1"
|
||||||
opencv = "4.12.0"
|
opencv = "4.12.0"
|
||||||
|
opencv_java = "4.9.0-0"
|
||||||
assertj = "3.27.6"
|
assertj = "3.27.6"
|
||||||
pdfbox = "2.0.27.0"
|
pdfbox = "2.0.27.0"
|
||||||
zoomable = "2.9.0"
|
zoomable = "2.9.0"
|
||||||
@@ -22,6 +23,7 @@ protobuf = "0.9.5"
|
|||||||
protobufJavaLite = "4.33.1"
|
protobufJavaLite = "4.33.1"
|
||||||
kotlinSerialization = "1.9.0"
|
kotlinSerialization = "1.9.0"
|
||||||
reorderable = "3.0.0"
|
reorderable = "3.0.0"
|
||||||
|
jetbrainsKotlinJvm = "2.2.21"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
@@ -54,6 +56,7 @@ litert = { group = "com.google.ai.edge.litert", name = "litert", version.ref = "
|
|||||||
litert-support = { group = "com.google.ai.edge.litert", name = "litert-support", version.ref = "litert" }
|
litert-support = { group = "com.google.ai.edge.litert", name = "litert-support", version.ref = "litert" }
|
||||||
litert-metadata = { group = "com.google.ai.edge.litert", name = "litert-metadata", version.ref = "litert" }
|
litert-metadata = { group = "com.google.ai.edge.litert", name = "litert-metadata", version.ref = "litert" }
|
||||||
opencv = { group="org.opencv", name="opencv", version.ref = "opencv" }
|
opencv = { group="org.opencv", name="opencv", version.ref = "opencv" }
|
||||||
|
opencvjava = { group="org.openpnp", name="opencv", version.ref = "opencv_java" }
|
||||||
pdfbox = { group = "com.tom-roush", name = "pdfbox-android", version.ref = "pdfbox" }
|
pdfbox = { group = "com.tom-roush", name = "pdfbox-android", version.ref = "pdfbox" }
|
||||||
zoomable = { group = "net.engawapg.lib", name = "zoomable", version.ref = "zoomable" }
|
zoomable = { group = "net.engawapg.lib", name = "zoomable", version.ref = "zoomable" }
|
||||||
reorderable = { module = "sh.calvin.reorderable:reorderable", version.ref = "reorderable" }
|
reorderable = { module = "sh.calvin.reorderable:reorderable", version.ref = "reorderable" }
|
||||||
@@ -70,3 +73,4 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi
|
|||||||
license = { id = "com.github.hierynomus.license", version.ref = "license" }
|
license = { id = "com.github.hierynomus.license", version.ref = "license" }
|
||||||
aboutLibrariesAndroid = { id = "com.mikepenz.aboutlibraries.plugin.android", version.ref = "aboutLibraries" }
|
aboutLibrariesAndroid = { id = "com.mikepenz.aboutlibraries.plugin.android", version.ref = "aboutLibraries" }
|
||||||
protobuf = { id = "com.google.protobuf", version.ref = "protobuf" }
|
protobuf = { id = "com.google.protobuf", version.ref = "protobuf" }
|
||||||
|
jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "jetbrainsKotlinJvm" }
|
||||||
|
|||||||
1
imageprocessing/.gitignore
vendored
Normal file
1
imageprocessing/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
19
imageprocessing/build.gradle.kts
Normal file
19
imageprocessing/build.gradle.kts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
plugins {
|
||||||
|
id("java-library")
|
||||||
|
alias(libs.plugins.jetbrains.kotlin.jvm)
|
||||||
|
}
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
|
}
|
||||||
|
kotlin {
|
||||||
|
compilerOptions {
|
||||||
|
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
implementation(libs.opencvjava)
|
||||||
|
|
||||||
|
testImplementation(kotlin("test"))
|
||||||
|
testImplementation(libs.assertj)
|
||||||
|
}
|
||||||
@@ -12,15 +12,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.fairscan.app.domain
|
package org.fairscan.imageprocessing
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import org.fairscan.imageprocessing.quad.detectDocumentQuadFromProbmap
|
||||||
import androidx.core.graphics.createBitmap
|
import org.fairscan.imageprocessing.quad.findQuadFromRightAngles
|
||||||
import org.fairscan.app.domain.ImageSegmentationService.Segmentation
|
import org.fairscan.imageprocessing.quad.minAreaRect
|
||||||
import org.fairscan.app.domain.quad.detectDocumentQuadFromProbmap
|
|
||||||
import org.fairscan.app.domain.quad.findQuadFromRightAngles
|
|
||||||
import org.fairscan.app.domain.quad.minAreaRect
|
|
||||||
import org.opencv.android.Utils
|
|
||||||
import org.opencv.core.Core
|
import org.opencv.core.Core
|
||||||
import org.opencv.core.CvType
|
import org.opencv.core.CvType
|
||||||
import org.opencv.core.Mat
|
import org.opencv.core.Mat
|
||||||
@@ -31,7 +27,13 @@ import org.opencv.imgproc.Imgproc
|
|||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
fun detectDocumentQuad(mask: Segmentation, isLiveAnalysis: Boolean, minQuadAreaRatio: Double = 0.02): Quad? {
|
interface Mask {
|
||||||
|
val width: Int
|
||||||
|
val height: Int
|
||||||
|
fun toMat(): Mat
|
||||||
|
}
|
||||||
|
|
||||||
|
fun detectDocumentQuad(mask: Mask, isLiveAnalysis: Boolean, minQuadAreaRatio: Double = 0.02): Quad? {
|
||||||
val mat = mask.toMat()
|
val mat = mask.toMat()
|
||||||
val (biggest: MatOfPoint2f?, area) = biggestContour(mat)
|
val (biggest: MatOfPoint2f?, area) = biggestContour(mat)
|
||||||
var vertices: List<Point>?
|
var vertices: List<Point>?
|
||||||
@@ -114,7 +116,7 @@ fun refineMask(original: Mat): Mat {
|
|||||||
return opened
|
return opened
|
||||||
}
|
}
|
||||||
|
|
||||||
fun extractDocument(originalBitmap: Bitmap, quad: Quad, rotationDegrees: Int): Bitmap {
|
fun extractDocument(inputMat: Mat, quad: Quad, rotationDegrees: Int): Mat {
|
||||||
val widthTop = norm(quad.topLeft, quad.topRight)
|
val widthTop = norm(quad.topLeft, quad.topRight)
|
||||||
val widthBottom = norm(quad.bottomLeft, quad.bottomRight)
|
val widthBottom = norm(quad.bottomLeft, quad.bottomRight)
|
||||||
val targetWidth = (widthTop + widthBottom) / 2
|
val targetWidth = (widthTop + widthBottom) / 2
|
||||||
@@ -137,8 +139,6 @@ fun extractDocument(originalBitmap: Bitmap, quad: Quad, rotationDegrees: Int): B
|
|||||||
)
|
)
|
||||||
val transform = Imgproc.getPerspectiveTransform(srcPoints, dstPoints)
|
val transform = Imgproc.getPerspectiveTransform(srcPoints, dstPoints)
|
||||||
|
|
||||||
val inputMat = Mat()
|
|
||||||
Utils.bitmapToMat(originalBitmap, inputMat)
|
|
||||||
val outputMat = Mat()
|
val outputMat = Mat()
|
||||||
val outputSize = Size(targetWidth.toDouble(), targetHeight.toDouble())
|
val outputSize = Size(targetWidth.toDouble(), targetHeight.toDouble())
|
||||||
Imgproc.warpPerspective(inputMat, outputMat, transform, outputSize)
|
Imgproc.warpPerspective(inputMat, outputMat, transform, outputSize)
|
||||||
@@ -147,7 +147,7 @@ fun extractDocument(originalBitmap: Bitmap, quad: Quad, rotationDegrees: Int): B
|
|||||||
val enhanced = enhanceCapturedImage(resized)
|
val enhanced = enhanceCapturedImage(resized)
|
||||||
val rotated = rotate(enhanced, rotationDegrees)
|
val rotated = rotate(enhanced, rotationDegrees)
|
||||||
|
|
||||||
return toBitmap(rotated)
|
return rotated
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resize(original: Mat, targetMax: Double): Mat {
|
fun resize(original: Mat, targetMax: Double): Mat {
|
||||||
@@ -177,12 +177,6 @@ fun rotate(input: Mat, degrees: Int): Mat {
|
|||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toBitmap(mat: Mat): Bitmap {
|
|
||||||
val outputBitmap = createBitmap(mat.cols(), mat.rows())
|
|
||||||
Utils.matToBitmap(mat, outputBitmap)
|
|
||||||
return outputBitmap
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Point.toCv(): org.opencv.core.Point {
|
fun Point.toCv(): org.opencv.core.Point {
|
||||||
return org.opencv.core.Point(x, y)
|
return org.opencv.core.Point(x, y)
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.fairscan.app.domain
|
package org.fairscan.imageprocessing
|
||||||
|
|
||||||
import kotlin.math.atan2
|
import kotlin.math.atan2
|
||||||
import kotlin.math.hypot
|
import kotlin.math.hypot
|
||||||
@@ -12,9 +12,8 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.fairscan.app.domain
|
package org.fairscan.imageprocessing
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import org.opencv.core.Core
|
import org.opencv.core.Core
|
||||||
import org.opencv.core.CvType
|
import org.opencv.core.CvType
|
||||||
import org.opencv.core.Mat
|
import org.opencv.core.Mat
|
||||||
@@ -25,12 +24,10 @@ import kotlin.math.max
|
|||||||
|
|
||||||
fun enhanceCapturedImage(img: Mat): Mat {
|
fun enhanceCapturedImage(img: Mat): Mat {
|
||||||
return if (isColoredDocument(img)) {
|
return if (isColoredDocument(img)) {
|
||||||
Log.i("PostProcessing", "color document")
|
|
||||||
val result = Mat()
|
val result = Mat()
|
||||||
Core.convertScaleAbs(img, result, 1.2, 10.0)
|
Core.convertScaleAbs(img, result, 1.2, 10.0)
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
Log.i("PostProcessing", "grayscale document")
|
|
||||||
val gray = multiScaleRetinex(img)
|
val gray = multiScaleRetinex(img)
|
||||||
val contrastedGray = enhanceContrastAuto(gray)
|
val contrastedGray = enhanceContrastAuto(gray)
|
||||||
val result = Mat()
|
val result = Mat()
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.fairscan.app.domain.quad
|
package org.fairscan.imageprocessing.quad
|
||||||
|
|
||||||
import org.opencv.core.Mat
|
import org.opencv.core.Mat
|
||||||
import org.opencv.core.CvType
|
import org.opencv.core.CvType
|
||||||
@@ -12,9 +12,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.fairscan.app.domain.quad
|
package org.fairscan.imageprocessing.quad
|
||||||
|
|
||||||
import org.fairscan.app.domain.Point
|
import org.fairscan.imageprocessing.Point
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
@@ -12,9 +12,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.fairscan.app.domain.quad
|
package org.fairscan.imageprocessing.quad
|
||||||
|
|
||||||
import org.fairscan.app.domain.Point
|
import org.fairscan.imageprocessing.Point
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.acos
|
import kotlin.math.acos
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.fairscan.app.domain
|
package org.fairscan.imageprocessing
|
||||||
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
@@ -21,4 +21,4 @@ dependencyResolutionManagement {
|
|||||||
|
|
||||||
rootProject.name = "FairScan"
|
rootProject.name = "FairScan"
|
||||||
include(":app")
|
include(":app")
|
||||||
|
include(":imageprocessing")
|
||||||
|
|||||||
Reference in New Issue
Block a user