Я попытался достичь функциональности кадрирования, которая похожа на cammscanner. Я использовал операцию преобразования GPUImage2 для выполнения преобразования перспективы. После операции фильтрации возвращается черное изображение.
Я обнаружил, что операция преобразования удаляет область контекста который мне нужно просмотреть. Пожалуйста, помогите мне разобраться в матрице для выполнения обрезки с помощью операции преобразования.
func getTransformedImage(originalimage: UIImage,newwidth: CGFloat,newheight: CGFloat,corner: [CGPoint]) -> UIImage{
let originalimage = originalimage
var src = RectQuard()
src.p1 = CGPoint(x: 0, y: 0)
src.p2 = CGPoint(x: newwidth - 1, y: 0)
src.p3 = CGPoint(x: newwidth - 1, y: newheight - 1)
src.p4 = CGPoint(x: 0, y: newheight-1)
var dst = RectQuard()
dst.p1 = CGPoint(x: corner[0].x, y: corner[0].y)
dst.p2 = CGPoint(x: corner[1].x, y: corner[1].y)
dst.p3 = CGPoint(x: corner[2].x, y: corner[2].y)
dst.p4 = CGPoint(x: corner[3].x, y: corner[3].y)
let transform_matrix = homographyMatrixFromSource(src: src,dst: dst)
let res_transform_matrix = Matrix4x4.init(transform_matrix)
let filter = TransformOperation()
filter.transform = res_transform_matrix
let cropped_image = originalimage.filterWithOperation(filter)
return cropped_image
}
func getGuassianElimination(input: [CGFloat],count: Int)-> [CGFloat]{
var A:[CGFloat] = input
var i:Int = 0
var j:Int = 0
let m:Int = count - 1
while (i < m && j < count){
// Find pivot in column j, starting in row i:
var maxi:Int = i
var k:Int = i + 1
while k < m {
if(fabsf(Float(A[k * count + j])) > fabsf(Float(A[maxi * count + j]))){
maxi = k
}
k = k + 1
}
if (A[maxi * count + j] != 0){
//swap rows i and maxi, but do not change the value of i
if(i != maxi){
var k:Int = 0
while k < count{
let aux: CGFloat = A[i * count + k]
A[ i * count + k]=A[maxi * count + k]
A[maxi * count + k] = aux
k = k + 1
}
}
//Now A[i,j] will contain the old value of A[maxi,j].
//divide each entry in row i by A[i,j]
let A_ij:CGFloat = A[i * count + j]
var k1:Int = 0
while k1 < count {
A[i*count+k]/=A_ij
k1 = k1 + 1
}
//Now A[i,j] will have the value 1.
var u:Int = i + 1
while u < m {
//subtract A[u,j] * row i from row u
let A_uj:CGFloat = A[u * count + j]
var k:Int = 0
while k < count{
A[u * count + k] -= A_uj * A[i * count + k]
k = k + 1
}
//Now A[u,j] will be 0, since A[u,j] - A[i,j] * A[u,j] = A[u,j] - 1 * A[u,j] = 0.
u = u + 1
}
i = i + 1
}
j = j + 1
}
var i1:Int = m - 2
while i1 >= 0{
var j:Int = i1 + 1
while j < count - 1{
A[i1 * count + m] -= A[i1 * count + j] * A[j * count + m]
j = j + 1
//A[i*n+j]=0;
}
i1 = i1 - 1
}
return A
}
func homographyMatrixFromSource(src: RectQuard,dst: RectQuard)-> CATransform3D{
var P: [[CGFloat]] = [
[-src.p1.x, -src.p1.y, -1, 0,0,0, src.p1.x*dst.p1.x, src.p1.y*dst.p1.x, -dst.p1.x ],
[0,0,0, -src.p1.x, -src.p1.y, -1, src.p1.x*dst.p1.y, src.p1.y*dst.p1.y, -dst.p1.y ],
[-src.p2.x, -src.p2.y, -1, 0, 0, 0, src.p2.x*dst.p2.x, src.p2.y*dst.p2.x, -dst.p2.x ],
[ 0, 0, 0, -src.p2.x, -src.p2.y, -1, src.p2.x*dst.p2.y, src.p2.y*dst.p2.y, -dst.p2.y ],
[-src.p3.x, -src.p3.y, -1, 0, 0, 0, src.p3.x*dst.p3.x, src.p3.y*dst.p3.x, -dst.p3.x ],
[0, 0, 0, -src.p3.x, -src.p3.y, -1, src.p3.x*dst.p3.y, src.p3.y*dst.p3.y, -dst.p3.y ],
[-src.p4.x, -src.p4.y, -1, 0, 0, 0, src.p4.x*dst.p4.x, src.p4.y*dst.p4.x, -dst.p4.x ],
[ 0, 0, 0, -src.p4.x, -src.p4.y, -1, src.p4.x*dst.p4.y, src.p4.y*dst.p4.y, -dst.p4.y ],
]
var temp_p = [CGFloat]()
for j in (0...7){
for k in (0...8)
{
temp_p.append(P[j][k])
}
}
temp_p = getGuassianElimination(input: temp_p,count: 9)
for temp in temp_p{
for i in (0...7){
for j in (0...8){
P[i][j] = temp
}
}
}
var matrix:CATransform3D = CATransform3DIdentity
matrix.m11 = P[0][8]
matrix.m21 = P[1][8]
matrix.m31 = 0
matrix.m41 = P[2][8]
matrix.m12 = P[3][8]
matrix.m22 = P[4][8]
matrix.m32 = 0
matrix.m42 = P[5][8]
matrix.m13 = 0
matrix.m23 = 0
matrix.m33 = 1
matrix.m43 = 0
matrix.m14 = P[6][8]
matrix.m24 = P[7][8]
matrix.m34 = 0
matrix.m44 = 1
return matrix
}
}