Example #1
0
Coord searchForLetter(Array2D<char> const& wsArray,
                      char                 c,
                      Coord const&         start)
{
    /**
      * @brief This function searches each row starting at the point start for the
      *        letter c. When it reaches the end of the row, it sets the x-coordinate
      *        to search for and goes down another row.
      */

    unsigned x = start.pX;
    for (unsigned y = start.pY; y < wsArray.getHeight(); ++y)
    {
        while (x < wsArray.getWidth())
        {
            //If the first character matches, check the word out.
            if (wsArray(x, y) == c)
                return Coord(x, y);

            ++x;
        }

        x = 0;
    }

    return Coord(wsArray.getWidth(), wsArray.getHeight());
}
Example #2
0
T Mask2D<T>::get(size_t n, Array2D<V> array, size_t h, size_t w) {
#ifdef __CUDA_ARCH__
    h += this->deviceMask[this->dimension*n];
    w += this->deviceMask[this->dimension*n+1];
    return (w<array.getWidth() && h<array.getHeight())?array(h,w):this->haloValue;
#else
    h += this->hostMask[this->dimension*n];
    w += this->hostMask[this->dimension*n+1];
    return (w<array.getWidth() && h<array.getHeight())?array(h,w):this->haloValue;
#endif
}
Example #3
0
bool isWordAtGivenDir(Array2D<char> const& wsArray,
                      std::string          str,
                      Coord const&         coord,
                      Direction            dir)
{
    /**
      * @brief Given the array to search in, the string to find, this function
      *        specifies whether or not the string is found at the position
      *        coord in the direction dir.
      */

    //First check if the word can be entirely contained within the wordsearch's
    //bounds.
    if ((coord.pX + (str.size() - 1) * dir.dX < 0) ||
        (coord.pX + (str.size() - 1) * dir.dX >= wsArray.getWidth()) ||
        (coord.pY + (str.size() - 1) * dir.dY < 0) ||
        (coord.pY + (str.size() - 1) * dir.dY >= wsArray.getHeight()))
        return false;

    //If you see any letter that doesn't match, you're done.
    for (unsigned i = 0; i != str.size(); ++i)
    {
        if (str[i] != wsArray(coord.pX + i * dir.dX, coord.pY + i * dir.dY))
            return false;
    }

    //One arrives here if and only if no letters that don't match are encountered,
    //i.e., the word IS found at the given coordinates and direction.
    return true;
}
Example #4
0
File: poi.C Project: wixor/ewo
POIvec extractPOIs(const Array2D<float> &eval, float threshold)
{
    int w = eval.getWidth(), h = eval.getHeight();

    POIvec all;
    for(int y=0; y<h; y++)
        for(int x=0; x<w; x++)
            if(eval[y][x] >= threshold)
                all.push_back(POI(x,y,eval[y][x]));
    std::sort(all.begin(), all.end());
    return all;
}
Example #5
0
void RawParameters::autoWB(const Array2D<uint16_t> & image) {
    Timer t("AutoWB");
    double dsum[4] = { 0.0, 0.0, 0.0, 0.0 };
    size_t dcount[4] = { 0, 0, 0, 0 };
    for (size_t row = 0; row < image.getHeight(); row += 8) {
        for (size_t col = 0; col < image.getWidth() ; col += 8) {
            double sum[4] = { 0.0, 0.0, 0.0, 0.0 };
            size_t count[4] = { 0, 0, 0, 0 };
            size_t ymax = std::min(row + 8, image.getHeight());
            size_t xmax = std::min(col + 8, image.getWidth());
            bool skipBlock = false;
            for (size_t y = row; y < ymax && !skipBlock; y++) {
                for (size_t x = col; x < xmax; x++) {
                    int c = FC(x, y);
                    uint16_t val = image(x, y);
                    if (val > max - 25) {
                        skipBlock = true;
                        break;
                    }
                    sum[c] += val;
                    count[c]++;
                }
            }
            if (!skipBlock) {
                for (int c = 0; c < 4; ++c) {
                    dsum[c] += sum[c];
                    dcount[c] += count[c];
                }
            }
        }
    }
    for (int c = 0; c < 4; ++c) {
        if (dsum[c] > 0.0) {
            camMul[c] = dcount[c] / dsum[c];
        } else {
            copy_n(preMul, 4, camMul);
            break;
        }
    }
}
Example #6
0
File: poi.C Project: wixor/ewo
Image visualizeEvaluation(const Array2D<float> &eval)
{
    int w = eval.getWidth(), h = eval.getHeight();

    float max = 0;
    for(int y = 0; y < h; y++)
        for(int x = 0; x < w; x++)
            max = std::max(max, eval[y][x]);

    Image ret(w,h);
    for(int y=0; y<h; y++)
        for(int x=0; x<w; x++)
            ret[y][x] = round(eval[y][x]/max*255.f);

    return ret;
}
Example #7
0
void setOccupied(Array2D<VecStr>& occupied,
                 std::string      str,
                 Coord const&     coord,
                 Direction const& dir)
{
    //Assert that you remain in the bounds; this is a "private" function, and
    //you should never leave the bounds when wsSolve() is called.
    assert((coord.pX + (str.size() - 1) * dir.dX >= 0) &&
           (coord.pX + (str.size() - 1) * dir.dX < occupied.getWidth()) &&
           (coord.pY + (str.size() - 1) * dir.dY >= 0) &&
           (coord.pY + (str.size() - 1) * dir.dY < occupied.getHeight()));

    //For each block that this string occupies, show that the block is occupied by
    //the string.
    for (unsigned i = 0; i < str.size(); ++i)
        occupied(coord.pX + i * dir.dX, coord.pY + i * dir.dY).push_back(str);
}
Example #8
0
bool areAllOccupiedBySuperstring(Array2D<VecStr> const& occupied,
                                 std::string            str,
                                 Coord const&           coord,
                                 Direction const&       dir)
{
    /**
      * @brief Given the array of squares in the wordsearch that are occupied,
      *        we check to see if the word str is "allowed" to be at the coord
      *        of ld and have direction dir. See wsSolveDoc.h for more information
      *        on what's "allowed" and what's not.
      */

    //Assert that you remain in the bounds; this is a "private" function, and
    //you should never leave the bounds when wsSolve() is called.
    assert((coord.pX + (str.size() - 1) * dir.dX >= 0) &&
           (coord.pX + (str.size() - 1) * dir.dX < occupied.getWidth()) &&
           (coord.pY + (str.size() - 1) * dir.dY >= 0) &&
           (coord.pY + (str.size() - 1) * dir.dY < occupied.getHeight()));

    //The string's length can't be 0.
    assert(str.size() != 0);

    //First check if the square that the first letter of str occupies is occupied
    //by any superstring of str. If not, exit; if so, make a list of them.
    VecStr firstVecStr = occupied(coord.pX, coord.pY);
    if (firstVecStr.size() == 0)
        return false;

    //Executes iff above code didn't return false.
    VecStr possibleSuperstrList;

    for (unsigned i = 0; i != firstVecStr.size(); ++i)
    {
        //The below statement is equivalent to "if str is not a substring of
        //firstVecStr[i].
        if (firstVecStr[i].find(str) == std::string::npos)
            return false;
        else
            possibleSuperstrList.push_back(firstVecStr[i]);
    }

    //If the string is only one letter long, and we didn't return false yet, it means
    //that the string is on a spot occupied by one of its superstrings. Hence, we
    //return true.
    if (str.size() == 1)
        return true;

    //Something important to note is that str can only be a substring of any
    //superstring of str if its first is contained by a superstring of str.
    //Therefore, the set of all possible superstrings of str that overlap with str
    //entirely has already been determined. In the following code, we either find a
    //square which is empty or does not contain a superstring of str (and therefore
    //we return false) or find a square in which some element of possibleSuperstrList
    //is not found on the square (implying that that element is not a superstring of
    //str that overlaps with str entirely; make sure you see why); we therefore
    //remove that element from possibleSuperStrList. In the end, any remaining elements
    //in possibleSuperstrList is definitely a superstring of str that overlaps with
    //str entirely; hence, if it is empty by the end, this function returns false,
    //and if it isn't empty, this function returns true.

    for (unsigned i = 1; i < str.size(); ++i)
    {
        //Vector obtained at the current position in the array.
        VecStr vecStrCurrent = occupied(coord.pX + i * dir.dX, coord.pY + i * dir.dY);

        //List of superstrings of str on the current square.
        VecStr superstrListCurrent;

        //If the vector is empty, the position is unoccupied.
        if (vecStrCurrent.size() == 0)
            return false;

        //See if str is a substring of any strings currently held in vecStrCurrent.
        for (unsigned j = 0; j != vecStrCurrent.size(); ++j)
        {
            //The below statement is equivalent to "if str is not a substring of
            //vecStrCurrent[i].
            if (vecStrCurrent[j].find(str) == std::string::npos)
                return false;
            else
                superstrListCurrent.push_back(vecStrCurrent[j]);
        }

        //Get rid of all the elements of possibleSuperstrList that don't appear in
        //vecSuperStrListCurrent. We do this by creating a new vector containing all
        //elements that DO appear in vecSuperStrListCurrent, and then copy
        //possibleSuperstrList to the new one.
        VecStr newPossibleSuperstrList;
        for (unsigned j = 0; j != possibleSuperstrList.size(); ++j)
        {
            for (unsigned k = 0; k != superstrListCurrent.size(); ++k)
            {
                if (possibleSuperstrList[j] == superstrListCurrent[k])
                {
                    newPossibleSuperstrList.push_back(possibleSuperstrList[j]);
                    break;
                }
            }
        }
        possibleSuperstrList = newPossibleSuperstrList;

        //If it's empty, you're done.
        if (possibleSuperstrList.size() == 0)
            return false;
    }

    //Reached if and only if the above code doesn't execute.
    return true;
}
Example #9
0
void wsSolve(Array2D<char> const& wsArray,       //Wordsearch array to solve.
             StrLocMap&           matchMap)      //List of words and their locations
{
    /**
      * @brief Given the array (wsArray) and the list of words to find (domain of
      *        matchMap), wsSolve will fill the range of matchMap with the locations
      *        of the words to find. For instance, if matchMap contains
      *        (string1, locationData), wsSolve() fills in locationData
      *        with the location of the string. If the word is not found,
      *        locationData will remain unmodified.
      *
      *        The algorithm itself is quite complex. See wsSolveDoc.h for more
      *        information.
      *
      * @author MPW
      * @date 7/19/2008
      * @version 1
      *
      */

   typedef std::vector<Coord> CoordVec;

   //Declare the array of vectors of strings and set them all to empty vectors.
   Array2D<VecStr> occupied(wsArray.getWidth(), wsArray.getHeight());

   for (unsigned y = 0; y != wsArray.getHeight(); ++y)
   {
       for (unsigned x = 0; x != wsArray.getWidth(); ++x)
           occupied(x, y) = std::vector<std::string>();
   }

    //Find the list of letters to make a location list for, and for each letter,
    //pair the letter with a vector containing the coordinates of each occurrence
    //of that letter.

    //We go through the list, finding each letter to cache.
    std::map<char, CoordVec> cacheList;
    char prevChar = 0;
    char currentChar = 0;
    for (StrLocMap::iterator itr = matchMap.begin(); itr != matchMap.end();)
    {
        //currentChar is still from the previous loop! Hence, we set prevChar to
        //currentChar and update currentChar.
        prevChar = currentChar;
        currentChar = itr->first[0];

        //If the letter here is the same as the one before, it repeats (since
        //maps sort their elements in alphabetical order) (if this is
        //the first loop, this will never happen; prevChar will be nul, and no first
        //letter of a string can be nul; therefore, we don't count the first element
        //as appearing twice).
        if (currentChar == prevChar)
        {
            cacheList.insert(std::make_pair(currentChar, CoordVec()));

            //This trasverses the map until we get to a different character.
            while ((++itr != matchMap.end()) && (itr->first[0] == currentChar));

            //This is so the ++itr below does not execute.
            continue;
        }

        ++itr;
    }

    //Copy each of the strings into a multimap; this will sort the strings by
    //length.
    std::multimap<unsigned, std::string> strList;
    for (StrLocMap::iterator itr = matchMap.begin(); itr != matchMap.end(); ++itr)
        strList.insert(std::make_pair(itr->first.size(), itr->first));

    //Start the find.
    for (std::multimap<unsigned, std::string>::reverse_iterator itr = strList.rbegin();
         itr != strList.rend(); ++itr)
    {
        std::string& str = itr->second;
        bool isCached = !(cacheList.find(str[0]) == cacheList.end()); //Whether or not
                                                                      //the first letter
                                                                      //of the current
                                                                      //string is
                                                                      //cached.

        Coord startLocation(0, 0); //Location to start searching at; if the first
                                   //letter of the word's locations have been cached,
                                   //and none of the cached positions are the
                                   //location where str is found, startLocation is
                                   //set to the spot one after the last cached
                                   //position.
        if (isCached)
        {
            CoordVec& coordVec = cacheList[str[0]];
            if (coordVec.size() != 0)
            {
                //We assert here that the cached locations are in "ascending order";
                //see wsSolveDoc.h for more information.

                for (unsigned i = 0; i != coordVec.size(); ++i)
                {
                    //Contains the list of all possible directions the word can have
                    //at the given coordinates; see wsSolveDoc.h for more information.
                    std::vector<Direction> possibleDirList;
                    findWordAt(wsArray, str, coordVec[i], possibleDirList);

                    //Go through the vector, either until we find a valid direction
                    //the word can have, or until there are no possible directions
                    //the word can have left. (There's a chance possibleDir.empty() is
                    //already true, so in that case, just skip over that part.)
                    for (std::vector<Direction>::iterator itr2 = possibleDirList.begin();
                         itr2 != possibleDirList.end(); ++itr2)
                    {
                        if (!areAllOccupiedBySuperstring(occupied, str, coordVec[i], *itr2))
                        {
                            //You found the word!
                            matchMap[str] = LocationData(coordVec[i], *itr2);
                            setOccupied(occupied, str, coordVec[i], *itr2);

                            goto lblContinue;
                        }
                    }
                }
            }
        }

        //If the word was found in a cache, we skip over to lblContinue; however, we
        //would then be skipping over some variable declarations in the current
        //scope. This is banned by C++ syntax, so we wrap the following code in
        //another block.
        {
            Coord const endLocation(wsArray.getWidth(), wsArray.getHeight());
            Coord       location(startLocation);

            //Find the next occurrence of the character you're searching for.
            while ((location = searchForLetter(wsArray, str[0], location)) != endLocation)
            {
                //Cache this position (if relevant).
                if (isCached)
                    cacheList[str[0]].push_back(location);

                //Contains the list of all possible directions the word can have
                //at the given coordinates; see wsSolveDoc.h for more information.
                std::vector<Direction> possibleDirList;
                findWordAt(wsArray, str, location, possibleDirList);

                for (std::vector<Direction>::iterator itr2 = possibleDirList.begin();
                     itr2 != possibleDirList.end(); ++itr2)
                {
                    if (!areAllOccupiedBySuperstring(occupied, str, location, *itr2))
                    {
                        //You found the word!
                        matchMap[str] = LocationData(location, *itr2);
                        setOccupied(occupied, str, location, *itr2);

                        //You're done with this loop; you then enter the next loop
                        //(i.e., you search for the next string.)
                        goto lblContinue;
                    }
                }
                //Increase the location's position by 1; if it goes past the end of
                //the row, go down another row.
                if (location.pX < wsArray.getWidth())
                    ++location.pX;
                else
                {
                    if (location.pY < wsArray.getHeight())
                    {
                        //This code executes if you're on the last position on the
                        //last row; in that case, you're done.
                        ++location.pY;
                        location.pX = 0;
                    }
                    else
                        break;
                }
            }
        }

        lblContinue:
        continue;
    }
}
Example #10
0
// From The GIMP: app/paint-funcs/paint-funcs.c:fatten_region
// SSE version by Ingo Weyrich
static Array2D<uint8_t> fattenMask(const Array2D<uint8_t> & mask, int radius) {
    Timer t("Fatten mask (SSE version)");
    size_t width = mask.getWidth(), height = mask.getHeight();
    Array2D<uint8_t> result(width, height);

    int circArray[2 * radius + 1]; // holds the y coords of the filter's mask
    // compute_border(circArray, radius)
    for (int i = 0; i < radius * 2 + 1; i++) {
        double tmp;
        if (i > radius)
            tmp = (i - radius) - 0.5;
        else if (i < radius)
            tmp = (radius - i) - 0.5;
        else
            tmp = 0.0;
        circArray[i] = int(std::sqrt(radius*radius - tmp*tmp));
    }
    // offset the circ pointer by radius so the range of the array
    //     is [-radius] to [radius]
    int * circ = circArray + radius;

    const uint8_t * bufArray[height + 2*radius];
    for (int i = 0; i < radius; i++) {
        bufArray[i] = &mask[0];
    }
    for (size_t i = 0; i < height; i++) {
        bufArray[i + radius] = &mask[i * width];
    }
    for (int i = 0; i < radius; i++) {
        bufArray[i + height + radius] = &mask[(height - 1) * width];
    }
    // offset the buf pointer
    const uint8_t ** buf = bufArray + radius;

    #pragma omp parallel
    {
        uint8_t buffer[width * (radius + 1)];
        uint8_t *maxArray[radius+1];
        for (int i = 0; i <= radius; i++) {
            maxArray[i] = &buffer[i*width];
        }

        #pragma omp for schedule(dynamic,16)
        for (size_t y = 0; y < height; y++) {
            size_t x = 0;
            for (; x < width-15; x+=16) { // compute max array, use SSE to process 16 bytes at once
                __m128i lmax = _mm_loadu_si128((__m128i*)&buf[y][x]);
                if(radius<2) // max[0] is only used when radius < 2
                    _mm_storeu_si128((__m128i*)&maxArray[0][x],lmax);
                for (int i = 1; i <= radius; i++) {
                    lmax = _mm_max_epu8(_mm_loadu_si128((__m128i*)&buf[y + i][x]),lmax);
                    lmax = _mm_max_epu8(_mm_loadu_si128((__m128i*)&buf[y - i][x]),lmax);
                    _mm_storeu_si128((__m128i*)&maxArray[i][x],lmax);
                }
            }
            for (; x < width; x++) { // compute max array, remaining columns
                uint8_t lmax = buf[y][x];
                if(radius<2) // max[0] is only used when radius < 2
                    maxArray[0][x] = lmax;
                for (int i = 1; i <= radius; i++) {
                    lmax = std::max(std::max(lmax, buf[y + i][x]), buf[y - i][x]);
                    maxArray[i][x] = lmax;
                }
            }

            for (x = 0; (int)x < radius; x++) { // render scan line, first columns without SSE
                uint8_t last_max = maxArray[circ[radius]][x+radius];
                for (int i = radius - 1; i >= -(int)x; i--)
                    last_max = std::max(last_max,maxArray[circ[i]][x + i]);
                result(x, y) = last_max;
            }
            for (; x < width-15-radius+1; x += 16) { // render scan line, use SSE to process 16 bytes at once
                __m128i last_maxv = _mm_loadu_si128((__m128i*)&maxArray[circ[radius]][x+radius]);
                for (int i = radius - 1; i >= -radius; i--)
                    last_maxv = _mm_max_epu8(last_maxv,_mm_loadu_si128((__m128i*)&maxArray[circ[i]][x+i]));
                _mm_storeu_si128((__m128i*)&result(x,y),last_maxv);
            }

            for (; x < width; x++) { // render scan line, last columns without SSE
                int maxRadius = std::min(radius,(int)((int)width-1-(int)x));
                uint8_t last_max = maxArray[circ[maxRadius]][x+maxRadius];
                for (int i = maxRadius-1; i >= -radius; i--)
                    last_max = std::max(last_max,maxArray[circ[i]][x + i]);
                result(x, y) = last_max;
            }
        }
    }

    return result;
}
Example #11
0
// From The GIMP: app/paint-funcs/paint-funcs.c:fatten_region
static Array2D<uint8_t> fattenMask(const Array2D<uint8_t> & mask, int radius) {
    Timer t("Fatten mask");
    size_t width = mask.getWidth(), height = mask.getHeight();
    Array2D<uint8_t> result(width, height);

    int circArray[2 * radius + 1]; // holds the y coords of the filter's mask
    // compute_border(circArray, radius)
    for (int i = 0; i < radius * 2 + 1; i++) {
        double tmp;
        if (i > radius)
            tmp = (i - radius) - 0.5;
        else if (i < radius)
            tmp = (radius - i) - 0.5;
        else
            tmp = 0.0;
        circArray[i] = int(std::sqrt(radius*radius - tmp*tmp));
    }
    // offset the circ pointer by radius so the range of the array
    //     is [-radius] to [radius]
    int * circ = circArray + radius;

    const uint8_t * bufArray[height + 2*radius];
    for (int i = 0; i < radius; i++) {
        bufArray[i] = &mask[0];
    }
    for (size_t i = 0; i < height; i++) {
        bufArray[i + radius] = &mask[i * width];
    }
    for (int i = 0; i < radius; i++) {
        bufArray[i + height + radius] = &mask[(height - 1) * width];
    }
    // offset the buf pointer
    const uint8_t ** buf = bufArray + radius;

    #pragma omp parallel
    {
        unique_ptr<uint8_t[]> buffer(new uint8_t[width * (radius + 1)]);
        unique_ptr<uint8_t *[]> maxArray;  // caches the largest values for each column
        maxArray.reset(new uint8_t *[width + 2 * radius]);
        for (int i = 0; i < radius; i++) {
            maxArray[i] = buffer.get();
        }
        for (size_t i = 0; i < width; i++) {
            maxArray[i + radius] = &buffer[(radius + 1) * i];
        }
        for (int i = 0; i < radius; i++) {
            maxArray[i + width + radius] = &buffer[(radius + 1) * (width - 1)];
        }
        // offset the max pointer
        uint8_t ** max = maxArray.get() + radius;

        #pragma omp for schedule(dynamic)
        for (size_t y = 0; y < height; y++) {
            uint8_t rowMax = 0;
            for (size_t x = 0; x < width; x++) { // compute max array
                max[x][0] = buf[y][x];
                for (int i = 1; i <= radius; i++) {
                    max[x][i] = std::max(std::max(max[x][i - 1], buf[y + i][x]), buf[y - i][x]);
                    rowMax = std::max(max[x][i], rowMax);
                }
            }

            uint8_t last_max = max[0][circ[-1]];
            int last_index = 1;
            for (size_t x = 0; x < width; x++) { // render scan line
                last_index--;
                if (last_index >= 0) {
                    if (last_max == rowMax) {
                        result(x, y) = rowMax;
                    } else {
                        last_max = 0;
                        for (int i = radius; i >= 0; i--)
                            if (last_max < max[x + i][circ[i]]) {
                                last_max = max[x + i][circ[i]];
                                last_index = i;
                            }
                        result(x, y) = last_max;
                    }
                } else {
                    last_index = radius;
                    last_max = max[x + radius][circ[radius]];

                    for (int i = radius - 1; i >= -radius; i--)
                        if (last_max < max[x + i][circ[i]]) {
                            last_max = max[x + i][circ[i]];
                            last_index = i;
                        }
                    result(x, y) = last_max;
                }
            }
        }
    }

    return result;
}