Skip to content

Commit

Permalink
Getting conversions from RGB to work directly on images
Browse files Browse the repository at this point in the history
  • Loading branch information
jonclayden committed Oct 24, 2019
1 parent 22bd6b0 commit 14e76ce
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 19 deletions.
4 changes: 2 additions & 2 deletions R/rgb.R
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ as.character.rgbArray <- function (x, ...)
#' @export
extractChannels <- function (array, channels = c("red","green","blue","alpha"), raw = FALSE)
{
if (!inherits(array, "rgbArray"))
if (!inherits(array,"niftiImage") && !inherits(array,"rgbArray"))
array <- rgbArray(array)

channels <- match.arg(channels, several.ok=TRUE)
Expand All @@ -63,6 +63,6 @@ extractChannels <- function (array, channels = c("red","green","blue","alpha"),
result <- .Call("unpackRgb", array, channelNumbers, PACKAGE="RNifti")
if (!raw)
storage.mode(result) <- "integer"
dimnames(result) <- list(NULL, channels)
dimnames(result) <- c(rep(list(NULL),ndim(array)), list(channels))
return (result)
}
31 changes: 15 additions & 16 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,16 @@ END_RCPP
RcppExport SEXP rgbToStrings (SEXP _object)
{
BEGIN_RCPP
IntegerVector array(_object);
const int channels = array.attr("channels");
const size_t len = Rf_length(array);

CharacterVector result(len);
for (size_t i=0; i<len; i++)
const NiftiImage image(_object, true, true);
const NiftiImageData data = image.data();
CharacterVector result(image.nVoxels());
for (size_t i=0; i<image.nVoxels(); i++)
{
rgba32_t rgba;
rgba.value.packed = array[i];
rgba.value.packed = int(data[i]);
std::ostringstream value;
value << "#" << std::hex << std::uppercase;
for (int j=0; j<channels; j++)
for (int j=0; j<image.nChannels(); j++)
value << std::setw(2) << std::setfill('0') << int(rgba.value.bytes[j]);
result[i] = value.str();
}
Expand All @@ -110,21 +108,22 @@ END_RCPP
RcppExport SEXP unpackRgb (SEXP _object, SEXP _channels)
{
BEGIN_RCPP
IntegerVector array(_object);
const NiftiImage image(_object, true, true);
const NiftiImageData data = image.data();
const int_vector channels = as<int_vector>(_channels);

int_vector dim = array.attr("dim");
int_vector dim = image.dim();
dim.push_back(channels.size());
const size_t len = Rf_length(array);

const size_t len = image.nVoxels();
RawVector result(len * channels.size());
rgba32_t rgba;
for (size_t i=0; i<len; i++)
{
rgba.value.packed = array[i];
for (int_vector::const_iterator it=channels.begin(); it<channels.end(); ++it)
rgba.value.packed = int(data[i]);
for (int j=0; j<channels.size(); j++)
{
const int channel = (*it) - 1;
result[i + len * channel] = rgba.value.bytes[channel];
const int channel = channels[j] - 1;
result[i + len * j] = int(rgba.value.bytes[channel]);
}
}
result.attr("dim") = dim;
Expand Down
4 changes: 3 additions & 1 deletion tests/testthat/test-08-composite.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ test_that("RGB datatypes are handled properly", {
k <- stats::kmeans(as.vector(image), 3L)
data <- rgbArray(k$cluster==1, k$cluster==2, k$cluster==3, dim=dim(image))
rgbImage <- updateNifti(data, image)
refValue <- rgbArray(diag(3))[k$cluster[40 + 39*96 + 29*9216]]
cluster <- k$cluster[40 + 39*96 + 29*9216]
refValue <- rgbArray(diag(3))[cluster]

expect_s3_class(data, "rgbArray")
expect_equal(rgbImage[40,40,30], refValue)
expect_equal(rgbImage$datatype, 128L)
expect_equal(rgbImage$bitpix, 24L)
expect_equivalent(unclass(data), unclass(as.array(rgbImage)))
expect_equivalent(extractChannels(rgbImage,c("red","green","blue")[cluster])[40,40,30,1], 255L)

writeNifti(rgbImage, tempPath)
header <- niftiHeader(tempPath)
Expand Down

0 comments on commit 14e76ce

Please sign in to comment.