Hi All,
I'm trying to iterate through each pixel in a view and calculate the average of the 9x9 pixels surrounding it. I initially tried following the convolution example, but it's performance isn't fast enough for my needs. I have tried several ways of iterating through the pixels on the 136x98 test image provided with the gil:
attempt #1 executes in ~400 ms
convolve_rows_fixed<rgb32f_pixel_t>(src1,kernel,dst);
convolve_cols_fixed<rgb32f_pixel_t>(dst,kernel,dst);
attempt #2 executes in ~26000 ms
vector<vector<double>> window(windowSizeX, vector<double> (windowSizeY, 1.0 / 81));
for (int y = 0; y <= src1.height(); ++y)
{
for (int x = 0; x < src1.width(); ++x)
{
for (int yi = y - windowRadiusY; yi <= y + windowRadiusY; ++yi)
{
if (yi >= 0 && yi <= src1.height())
{
typename SrcView1::x_iterator src1_it=src1.row_begin(y);
typename SrcView2::x_iterator src2_it=src2.row_begin(y);
typename DstView::x_iterator dst_it=dst.row_begin(y);
for (int xi = x - windowRadiusX; xi <= x + windowRadiusX; ++xi)
{
vector<double> ux, ux2, uy, uy2, uxy = vector<double>(numChannels, 0);
ux = ux2 = uy = uy2 = uxy;
if (xi >= 0 && xi <= src1.width())
{
int winX = xi - x + windowRadiusX;
int winY = yi - y + windowRadiusY;
double winTotal = 0;
for (int c = 0; c < numChannels; ++c)
{
ux[c] += window[winX][winY] * typename SrcView1::value_type(src1_it[xi])[c];
winTotal += window[winX][winY];
}
// Normalize calculation
for (int c = 0; c < numChannels; ++c)
{
ux[c] = ux[c] / winTotal;
}
}
}
}
}
}
}
So now I'm attempting to run the following but having trouble:
...
template <typename SrcView1, typename SrcView2, typename DstView>
double function(const SrcView1& src1, const SrcView2& src2, const DstView& dst)
{
typedef typename channel_type<DstView>::type dstChannelType;
transform_pixel_positions(src1, src2, dst, operator<dstChannelType>());
}
...
template <typename Out>
struct operator
{
template <typename T> Out operator()(const T& in1, const T& in2) const
{
rgb8_view_t subView1 = rgb8_view_t(9,9,in1); // in1 throws type mismatch
rgb8_view_t subView2 = rgb8_view_t(9,9,in2); // in2 throws type mismatch
Out retVal;
transform_pixels(subView1, subView2, retVal, average());
return rgb8_pixel_t(0,0,0);
}
};
Can you explain if this is an appropriate way to construct a subview and how I can retrieve the locator needed as the 3rd parameter to rgb8_view_t(), specifically I need the locator for 4 pixels left and 4 pixel up so that the average window is centered on in1/in2? Also, is it possible to get the view type from the locator inputs in1 and in2 so that I can change the subView instantiantion to in1Type subView1 = in1Type(9,9,in1)?
It seems that the performance, with regard to speed, is much better using transform_pixel or transform_pixel_positions over iterating through the pixels myself unless I am doing something incorrect. Are there any other programming styles that provide better performance for doing similar calculations on groups of pixels?
As always, I greatly appreciate any help as I'm learning.
Thanks,
Mark Sapp