完成SCA:蚕茧模块演示效果
This commit is contained in:
@@ -15,7 +15,8 @@ import io.ktor.server.application.*
|
||||
import io.ktor.server.tomcat.jakarta.*
|
||||
|
||||
|
||||
const val VIDEO_INPUT_PATH = "/tmp/"
|
||||
//const val VIDEO_INPUT_PATH = "/tmp/"
|
||||
const val VIDEO_INPUT_PATH = "C:/tmp/"
|
||||
|
||||
/**
|
||||
* 服务器地址
|
||||
|
||||
@@ -16,7 +16,6 @@ object ImageDao {
|
||||
fun insertImageAnalyticsData(request: ImageAnalyticsRequest) {
|
||||
return transaction {
|
||||
ImageTable.insert {
|
||||
it[object_name] = request.object_name
|
||||
it[upload_datetime] = Timestamp.valueOf(request.upload_datetime)
|
||||
.toLocalDateTime().toKotlinLocalDateTime()
|
||||
it[file_name] = request.file_name
|
||||
@@ -34,15 +33,19 @@ object ImageDao {
|
||||
}
|
||||
|
||||
|
||||
fun getVideoList(): List<ImageAnalyticsRequest> {
|
||||
fun getImageList(name: String): List<ImageAnalyticsRequest> {
|
||||
return transaction {
|
||||
ImageTable.selectAll()
|
||||
.where { ImageTable.name like "%$name%" }
|
||||
.orderBy(ImageTable.upload_datetime, SortOrder.DESC)
|
||||
.map {
|
||||
ImageAnalyticsRequest(
|
||||
object_name = "http://${SERVER_PATH_OSS}:9000/image/" + it[ImageTable.object_name],
|
||||
id = it[ImageTable.id].value,
|
||||
name = it[ImageTable.name],
|
||||
upload_datetime = formatLocalDateTimeToString(it[ImageTable.upload_datetime]),
|
||||
file_name = it[ImageTable.file_name],
|
||||
image_pre = "http://${SERVER_PATH_OSS}:9000/image-sca/" + it[ImageTable.image_pre],
|
||||
image_after = "http://${SERVER_PATH_OSS}:9000/image-sca/" + it[ImageTable.image_after],
|
||||
resolution = it[ImageTable.resolution],
|
||||
size = it[ImageTable.size],
|
||||
cocoon_count = it[ImageTable.cocoon_count],
|
||||
|
||||
@@ -72,7 +72,6 @@ object VideoDao {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getAnalyticsDetailByVideoId(vId: Int): ResultRow? {
|
||||
return transaction {
|
||||
VideoTable.selectAll().where { VideoTable.id eq vId }.singleOrNull()
|
||||
|
||||
@@ -6,10 +6,12 @@ import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.v1.datetime.datetime
|
||||
import org.jetbrains.exposed.v1.json.json
|
||||
|
||||
object ImageTable : IntIdTable("image") {
|
||||
val object_name = varchar("object_name", 255)
|
||||
object ImageTable : IntIdTable("image_sca") {
|
||||
val name = varchar("name", 255)
|
||||
val upload_datetime = datetime("upload_datetime")
|
||||
val file_name = varchar("file_name", 255)
|
||||
val image_pre = varchar("image_pre", 255)
|
||||
val image_after = varchar("image_after", 255)
|
||||
val resolution = varchar("resolution", 255)
|
||||
val size = float("size")
|
||||
val cocoon_count = float("cocoon_count")
|
||||
|
||||
@@ -4,10 +4,13 @@ import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ImageAnalyticsRequest(
|
||||
val object_name: String, // Minio存储名
|
||||
val id : Int,
|
||||
val name : String,
|
||||
val upload_datetime: String, // 上传时间
|
||||
val file_name: String, // 文件名
|
||||
val resolution: String, // 图片分辨率
|
||||
val image_after: String,
|
||||
val image_pre: String,
|
||||
val size: Float, // 文件大小,单位MB
|
||||
val cocoon_count: Float, // 识别出的茧数量
|
||||
val max_confidence: Float, // 最大置信度
|
||||
|
||||
@@ -9,9 +9,9 @@ import io.ktor.server.routing.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
|
||||
fun Application.ImageAnalytics() {
|
||||
fun Application.ImageAnalytics() {
|
||||
routing {
|
||||
route("/api") {
|
||||
route("/api/sca") {
|
||||
// 上传分析结果
|
||||
post("/saveImageAnalyticsData") {
|
||||
val request = call.receive<ImageAnalyticsRequest>()
|
||||
@@ -28,9 +28,10 @@ fun Application.ImageAnalytics() {
|
||||
stopHLSStream(camera)
|
||||
call.respond(BaseResponse(message = "摄像头流已停止", data = null))
|
||||
}
|
||||
// 获取已分析视频列表
|
||||
// 获取已分析图片列表
|
||||
get("/getImageList") {
|
||||
val res = ImageDao.getVideoList()
|
||||
val name = call.parameters["name"]
|
||||
val res = ImageDao.getImageList(name ?: "")
|
||||
call.respond(BaseResponse(data = res))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package ink.snowflake.server.route
|
||||
|
||||
import ink.snowflake.server.SERVER_PATH_OSS
|
||||
import ink.snowflake.server.VIDEO_INPUT_PATH
|
||||
import ink.snowflake.server.database.VideoDao
|
||||
import ink.snowflake.server.database.table.VideoTable
|
||||
import ink.snowflake.server.database.table.VideoTable.vAAverageMaskedRatio
|
||||
import ink.snowflake.server.database.table.VideoTable.vACountPeople
|
||||
@@ -12,17 +13,19 @@ import ink.snowflake.server.database.table.VideoTable.vStartDateTime
|
||||
import ink.snowflake.server.model.request.VideoAnalyticsRequest
|
||||
import ink.snowflake.server.model.response.*
|
||||
import ink.snowflake.server.utils.WebSocketManager.broadcastMessage
|
||||
import ink.snowflake.server.database.VideoDao
|
||||
import ink.snowflake.server.utils.runCommand
|
||||
import io.ktor.http.content.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.auth.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.websocket.*
|
||||
import io.ktor.websocket.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.consumeEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import kotlinx.datetime.toJavaLocalDateTime
|
||||
import java.io.File
|
||||
@@ -67,8 +70,7 @@ fun Application.VideoAnalytics() {
|
||||
clients.remove(this) // 确保在连接关闭时移除客户端
|
||||
}
|
||||
}
|
||||
route("/api") {
|
||||
route("/iva") {
|
||||
route("/api/iva") {
|
||||
// 上传分析结果
|
||||
post("/saveVideoAnalyticsData") {
|
||||
val request = call.receive<VideoAnalyticsRequest>()
|
||||
@@ -76,7 +78,7 @@ fun Application.VideoAnalytics() {
|
||||
call.respond(BaseResponse(data = VideoDao.insertVideoAnalyticsData(request)))
|
||||
}
|
||||
authenticate {
|
||||
post("/upload") {
|
||||
post("/createVideoTask") {
|
||||
val multipart = call.receiveMultipart() //1G
|
||||
// 确保 uploads 目录存在
|
||||
val uploadDir = File(VIDEO_INPUT_PATH)
|
||||
@@ -90,32 +92,35 @@ fun Application.VideoAnalytics() {
|
||||
var name = ""
|
||||
var datetime = ""
|
||||
broadcastMessage("正在上传数据")
|
||||
multipart.forEachPart { part ->
|
||||
when (part) {
|
||||
is PartData.FileItem -> {
|
||||
fileName = part.originalFileName ?: "unknown"
|
||||
val file = File("$VIDEO_INPUT_PATH$fileName") // 保存路径
|
||||
//ktor3
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
multipart.forEachPart { part ->
|
||||
when (part) {
|
||||
is PartData.FileItem -> {
|
||||
fileName = part.originalFileName ?: "unknown"
|
||||
val file = File("$VIDEO_INPUT_PATH$fileName") // 保存路径
|
||||
//ktor3
|
||||
// file.outputStream().use { outputStream ->
|
||||
// val writableChannel = Channels.newChannel(outputStream)
|
||||
// part.provider().copyTo(writableChannel) // 复制到 WritableByteChannel
|
||||
// }
|
||||
//ktor2
|
||||
part.streamProvider().use { inputStream ->
|
||||
file.outputStream().buffered().use { outputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
//ktor2
|
||||
part.streamProvider().use { inputStream ->
|
||||
file.outputStream().buffered().use { outputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is PartData.FormItem -> {
|
||||
when (part.name) {
|
||||
"name" -> name = part.value
|
||||
"datetime" -> datetime = part.value
|
||||
is PartData.FormItem -> {
|
||||
when (part.name) {
|
||||
"projectName" -> name = part.value
|
||||
"projectDatetime" -> datetime = part.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> part.dispose()
|
||||
else -> part.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
call.respond(BaseResponse(message = "上传成功", data = null))
|
||||
@@ -267,7 +272,6 @@ fun Application.VideoAnalytics() {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user