From 094d5158a685a62866db24dff364c746df0f2cb4 Mon Sep 17 00:00:00 2001 From: Markus Noga Date: Fri, 19 Jun 2020 01:00:12 +0200 Subject: [PATCH] towards #5: experimental debayering code for RGGB color filter array --- internal/debayer.go | 155 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 internal/debayer.go diff --git a/internal/debayer.go b/internal/debayer.go new file mode 100644 index 0000000..275eabf --- /dev/null +++ b/internal/debayer.go @@ -0,0 +1,155 @@ +// Copyright (C) 2020 Markus L. Noga +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +package internal + + +// Color filter array type, from top to bottom and left to right +type CFAType int +const ( + CFATypeRGGB CFAType = iota + CFATypeGRBG + CFATypeGBRG + CFATypeBGGR +) + +// Textual names for color filter array types. Indexed by CFAType +var CFANames=[]string{"RGGB", "GRBG", "GBRG", "BGGR"} + + +func DebayerBilinearToRed(data []float32, width int32, cfaType CFAType) (rs []float32, adjWidth int32) { + switch cfaType { + case CFATypeRGGB: + return DebayerBilinearRGGBToRed(data, width) + } + LogFatalf("Unimplemented CFA type for debayering: %d\n", cfaType) + return nil, 0 // never reached +} + +func DebayerBilinearRGGBToRed(data []float32, width int32) (rs []float32, adjWidth int32) { + height :=int32(len(data))/width + adjWidth =width & ^1 // ignore last column and row in odd-sized images + adjHeight:=height & ^1 + rs =GetArrayOfFloat32FromPool(int(adjWidth)*int(adjHeight)) + + // for all pixels in adjusted range + for row:=int32(0); row=2 { + g1Left=data[srcOffset-1 ] + if row>=2 { + g2Up=data[srcOffset-1-width] + } + } + g2Right, g1Down:=g2, 0.5*(g1+g2) + if col=2 { + bLeft=data[srcOffset-1+width] + if row>=2 { + bUp=data[srcOffset+1-width] + bLU=data[srcOffset-1-width] + } + } else if row>=2 { + bUp=data[srcOffset+1-width] + } + + // interpolate and write blue values + bs[destOffset ]=0.25*(b+bLeft+bUp+bLU) + bs[destOffset+1 ]=0.5 *(b+bUp) + bs[destOffset +adjWidth]=0.5 *(b+bLeft) + bs[destOffset+1+adjWidth]= b + } + } + + return bs, adjWidth +} +