光电挠度仪
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

181 lines
5.8 KiB

import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Matrix
import androidx.camera.core.ImageProxy
import com.example.myopencv.imageHandler
import com.example.myopencv.models.CentroidPoint
import org.opencv.android.Utils
import org.opencv.core.CvType
import org.opencv.core.Mat
import org.opencv.core.Point
import org.opencv.core.Rect
import org.opencv.core.Scalar
import org.opencv.imgproc.Imgproc
class ImageHandler {
fun mat2bitMap(mat: Mat): Bitmap {
val bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.RGB_565)
Utils.matToBitmap(mat, bitmap)
return bitmap
}
fun mat2gary(mat: Mat): Mat {
//灰度
val garyMat = Mat(mat.width(), mat.height(), CvType.CV_8UC3)
Imgproc.cvtColor(mat, garyMat, Imgproc.COLOR_RGB2GRAY)
return garyMat
}
//图片二值化
fun binaryMat(thresholdValue: Double, mat: Mat): Mat {
// 设置二值化的最大值
val maxValue = 255.0
val binaryMat = Mat(mat.width(), mat.height(), CvType.CV_8UC3)
// 进行二值化操作
Imgproc.threshold(mat, binaryMat, thresholdValue, maxValue, Imgproc.THRESH_BINARY)
return binaryMat
}
fun binaryBitMap(thresholdValue: Double, mat: Mat): Bitmap {
// 设置二值化的最大值
val binaryMat = binaryMat(thresholdValue, mat)
val bitmap = mat2bitMap(binaryMat)
return bitmap
}
//图片加文字
fun tagText2mat(content: String, mat: Mat): Bitmap {
val point1 = Point(100.0, 100.0)
val point2 = Point(300.0, 300.0)
val color = Scalar(0.0, 0.0, 255.0)
Imgproc.line(mat, point1, point2, color, 5)
Imgproc.putText(mat, content, point1, 1, 10.0, color, 5)
val bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.RGB_565)
Utils.matToBitmap(mat, bitmap)
return bitmap
}
//裁剪图片指定区域
fun cropMat(mat: Mat,x: Int, y: Int, width: Int, height: Int): Mat {
val subMat: Mat = Mat(mat, Rect(x, y, width, height))
return subMat
}
//裁剪图片指定区域 并生成点位图
fun cropMat2bitMap(x: Int, y: Int, width: Int, height: Int, mat: Mat): Bitmap {
val subMat: Mat = Mat(mat, Rect(x, y, width, height))
val bitmap = Bitmap.createBitmap(subMat.width(), subMat.height(), Bitmap.Config.RGB_565)
Utils.matToBitmap(subMat, bitmap)
return bitmap
}
//计算质量心
fun calcMoments(binary: Mat): Point {
var center = Point(0.0, 0.0)
val moments = Imgproc.moments(binary)
val area = moments.m00
// 如果面积为0,则质心不存在
if (area != 0.0) {
val cx = moments.m10 / area
val cy = moments.m01 / area
center = Point(cx.toDouble(), cy.toDouble())
//println("质心: (${center.x}, ${center.y})")
} else {
println("质心不存在")
}
return center
}
fun rotateBitmap(original: Bitmap, degrees: Float): Bitmap {
// 创建一个新的Bitmap对象,具有与原始Bitmap相同的配置
val rotated = Bitmap.createBitmap(
original, 0, 0, original.width, original.height, null, false
)
// 创建Matrix对象
val matrix = Matrix()
// 设置旋转角度和旋转中心
matrix.postRotate(degrees, (original.width/2).toFloat(), (original.height/2).toFloat())
// 创建一个新的Canvas对象,并使用Matrix进行变换
val canvas = android.graphics.Canvas(rotated)
canvas.drawBitmap(original, matrix, null)
// 返回旋转后的Bitmap
return rotated
}
fun img2Moments(image: ImageProxy,threshold: Int,x: Int,y: Int,w: Int,h: Int):CentroidPoint{
val bitImg=image.toBitmap()
val rawMat=Mat(bitImg.width, bitImg.height, CvType.CV_8UC3)
Utils.bitmapToMat(bitImg,rawMat)
val subMat= imageHandler.cropMat(rawMat,x,y,w,h)
//灰度
val garyMat =imageHandler.mat2gary(subMat)
//二值化
val binaryMat=imageHandler.binaryMat(threshold.toDouble(),garyMat)
val center=imageHandler.calcMoments(binaryMat)
return CentroidPoint(center.x,center.y)
}
fun bitMap2Gray(bitImg: Bitmap):Bitmap{
val rawMat=Mat(bitImg.width, bitImg.height, CvType.CV_8UC3)
Utils.bitmapToMat(bitImg,rawMat)
//灰度
val garyMat =imageHandler.mat2gary(rawMat)
Utils.matToBitmap(garyMat,bitImg)
return bitImg
}
//外包的计算方法
fun getBinImageCentroid(image: Bitmap, threshold: Int, viewport: android.graphics.Rect): CentroidPoint {
val rect = android.graphics.Rect(0, 0, image.width, image.height)
val left = Math.max(viewport.left, rect.left)
val right = Math.min(viewport.right, rect.right)
val top = Math.max(viewport.top, rect.top)
val bottom = Math.min(viewport.bottom, rect.bottom)
var sumA = 0L
var sumX = 0L
var sumY = 0L
for (y in top until bottom) {
for (x in left until right) {
val pixel = image.getPixel(x, y)
val r = Color.red(pixel)
val g = Color.green(pixel)
val b = Color.blue(pixel)
val gary = qGary(r, g, b)
if (gary >= threshold) {
val v=255
sumA += v
sumX += v * (x - left)
sumY += v * (y - top)
}
}
}
val cp = if (sumA == 0L)
CentroidPoint(0.0,0.0)
else {
CentroidPoint(-1.0 * sumX / sumA, 1.0 * sumY / sumA)
}
return cp
}
fun qGary(r :Int,g :Int ,b :Int):Int{
return (r*11+g*16+b*5)/32
}
}