本文整理汇总了C++中pixRasterop函数的典型用法代码示例。如果您正苦于以下问题:C++ pixRasterop函数的具体用法?C++ pixRasterop怎么用?C++ pixRasterop使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了pixRasterop函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: boxBoundingRegion
// create a union of two arbitrary pix
Pix *CubeLineSegmenter::PixUnion(Pix *dest_pix, Box *dest_box,
Pix *src_pix, Box *src_box) {
// compute dimensions of union rect
BOX *union_box = boxBoundingRegion(src_box, dest_box);
// create the union pix
Pix *union_pix = pixCreate(union_box->w, union_box->h, src_pix->d);
if (union_pix == NULL) {
return NULL;
}
// blt the src and dest pix
pixRasterop(union_pix,
src_box->x - union_box->x, src_box->y - union_box->y,
src_box->w, src_box->h, PIX_SRC | PIX_DST, src_pix, 0, 0);
pixRasterop(union_pix,
dest_box->x - union_box->x, dest_box->y - union_box->y,
dest_box->w, dest_box->h, PIX_SRC | PIX_DST, dest_pix, 0, 0);
// replace the dest_box
*dest_box = *union_box;
boxDestroy(&union_box);
return union_pix;
}
示例2: pixTilingPaintTile
/*!
* \brief pixTilingPaintTile()
*
* \param[in] pixd dest: paint tile onto this, without overlap
* \param[in] i tile row index
* \param[in] j tile column index
* \param[in] pixs source: tile to be painted from
* \param[in] pt pixtiling struct
* \return 0 if OK, 1 on error
*/
l_int32
pixTilingPaintTile(PIX *pixd,
l_int32 i,
l_int32 j,
PIX *pixs,
PIXTILING *pt)
{
l_int32 w, h;
PROCNAME("pixTilingPaintTile");
if (!pixd)
return ERROR_INT("pixd not defined", procName, 1);
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if (!pt)
return ERROR_INT("pt not defined", procName, 1);
if (i < 0 || i >= pt->ny)
return ERROR_INT("invalid row index i", procName, 1);
if (j < 0 || j >= pt->nx)
return ERROR_INT("invalid column index j", procName, 1);
/* Strip added border pixels off if requested */
pixGetDimensions(pixs, &w, &h, NULL);
if (pt->strip == TRUE) {
pixRasterop(pixd, j * pt->w, i * pt->h,
w - 2 * pt->xoverlap, h - 2 * pt->yoverlap, PIX_SRC,
pixs, pt->xoverlap, pt->yoverlap);
} else {
pixRasterop(pixd, j * pt->w, i * pt->h, w, h, PIX_SRC, pixs, 0, 0);
}
return 0;
}
示例3: Java_com_example_ocr_Pixa_nativeMergeAndReplacePix
void Java_com_example_ocr_Pixa_nativeMergeAndReplacePix(JNIEnv *env, jclass clazz,
jint nativePixa,
jint indexA, jint indexB) {
PIXA *pixa = (PIXA *) nativePixa;
l_int32 op;
l_int32 x, y, w, h;
l_int32 dx, dy, dw, dh;
PIX *pixs, *pixd;
BOX *boxA, *boxB, *boxd;
boxA = pixaGetBox(pixa, indexA, L_CLONE);
boxB = pixaGetBox(pixa, indexB, L_CLONE);
boxd = boxBoundingRegion(boxA, boxB);
boxGetGeometry(boxd, &x, &y, &w, &h);
pixd = pixCreate(w, h, 1);
op = PIX_SRC | PIX_DST;
pixs = pixaGetPix(pixa, indexA, L_CLONE);
boxGetGeometry(boxA, &dx, &dy, &dw, &dh);
pixRasterop(pixd, dx - x, dy - y, dw, dh, op, pixs, 0, 0);
pixDestroy(&pixs);
boxDestroy(&boxA);
pixs = pixaGetPix(pixa, indexB, L_CLONE);
boxGetGeometry(boxB, &dx, &dy, &dw, &dh);
pixRasterop(pixd, dx - x, dy - y, dw, dh, op, pixs, 0, 0);
pixDestroy(&pixs);
boxDestroy(&boxB);
pixaReplacePix(pixa, indexA, pixd, boxd);
}
示例4: pixRasteropHip
/*!
* pixRasteropHip()
*
* Input: pixd (in-place operation)
* by (top of horizontal band)
* bh (height of horizontal band)
* hshift (horizontal shift of band; hshift > 0 is to right)
* incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
* Return: 0 if OK; 1 on error
*
* Notes:
* (1) This rasterop translates a horizontal band of the
* image either left or right, bringing in either white
* or black pixels from outside the image.
* (2) The horizontal band extends the full width of pixd.
* (3) If a colormap exists, the nearest color to white or black
* is brought in.
*/
l_int32
pixRasteropHip(PIX *pixd,
l_int32 by,
l_int32 bh,
l_int32 hshift,
l_int32 incolor)
{
l_int32 w, h, d, index, op;
PIX *pixt;
PIXCMAP *cmap;
PROCNAME("pixRasteropHip");
if (!pixd)
return ERROR_INT("pixd not defined", procName, 1);
if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
return ERROR_INT("invalid value for incolor", procName, 1);
if (bh <= 0)
return ERROR_INT("bh must be > 0", procName, 1);
if (hshift == 0)
return 0;
pixGetDimensions(pixd, &w, &h, &d);
rasteropHipLow(pixGetData(pixd), h, d, pixGetWpl(pixd), by, bh, hshift);
cmap = pixGetColormap(pixd);
if (!cmap) {
if ((d == 1 && incolor == L_BRING_IN_BLACK) ||
(d > 1 && incolor == L_BRING_IN_WHITE))
op = PIX_SET;
else
op = PIX_CLR;
/* Set the pixels brought in at left or right */
if (hshift > 0)
pixRasterop(pixd, 0, by, hshift, bh, op, NULL, 0, 0);
else /* hshift < 0 */
pixRasterop(pixd, w + hshift, by, -hshift, bh, op, NULL, 0, 0);
return 0;
}
/* Get the nearest index and fill with that */
if (incolor == L_BRING_IN_BLACK)
pixcmapGetRankIntensity(cmap, 0.0, &index);
else /* white */
pixcmapGetRankIntensity(cmap, 1.0, &index);
pixt = pixCreate(L_ABS(hshift), bh, d);
pixSetAllArbitrary(pixt, index);
if (hshift > 0)
pixRasterop(pixd, 0, by, hshift, bh, PIX_SRC, pixt, 0, 0);
else /* hshift < 0 */
pixRasterop(pixd, w + hshift, by, -hshift, bh, PIX_SRC, pixt, 0, 0);
pixDestroy(&pixt);
return 0;
}
示例5: main
main(int argc,
char **argv)
{
l_int32 w, h, d, n;
char *filein1, *filein2, *fileout;
PIX *pixs1, *pixs2, *pixd;
static char mainName[] = "bincompare";
if (argc != 4)
exit(ERROR_INT(" Syntax: bincompare filein1 filein2 fileout",
mainName, 1));
filein1 = argv[1];
filein2 = argv[2];
fileout = argv[3];
if ((pixs1 = pixRead(filein1)) == NULL)
exit(ERROR_INT("pixs1 not made", mainName, 1));
if ((pixs2 = pixRead(filein2)) == NULL)
exit(ERROR_INT("pixs2 not made", mainName, 1));
w = pixGetWidth(pixs1);
h = pixGetHeight(pixs1);
d = pixGetDepth(pixs1);
if (d != 1)
exit(ERROR_INT("pixs1 not binary", mainName, 1));
pixCountPixels(pixs1, &n, NULL);
fprintf(stderr, "Number of fg pixels in file1 = %d\n", n);
pixCountPixels(pixs2, &n, NULL);
fprintf(stderr, "Number of fg pixels in file2 = %d\n", n);
#if XOR
fprintf(stderr, "xor: 1 ^ 2\n");
pixRasterop(pixs1, 0, 0, w, h, PIX_SRC ^ PIX_DST, pixs2, 0, 0);
pixCountPixels(pixs1, &n, NULL);
fprintf(stderr, "Number of fg pixels in XOR = %d\n", n);
pixWrite(fileout, pixs1, IFF_PNG);
#elif SUBTRACT_1_FROM_2
fprintf(stderr, "subtract: 2 - 1\n");
pixRasterop(pixs1, 0, 0, w, h, PIX_SRC & PIX_NOT(PIX_DST), pixs2, 0, 0);
pixCountPixels(pixs1, &n, NULL);
fprintf(stderr, "Number of fg pixels in 2 - 1 = %d\n", n);
pixWrite(fileout, pixs1, IFF_PNG);
#elif SUBTRACT_2_FROM_1
fprintf(stderr, "subtract: 1 - 2\n");
pixRasterop(pixs1, 0, 0, w, h, PIX_DST & PIX_NOT(PIX_SRC), pixs2, 0, 0);
pixCountPixels(pixs1, &n, NULL);
fprintf(stderr, "Number of fg pixels in 1 - 2 = %d\n", n);
pixWrite(fileout, pixs1, IFF_PNG);
#else
fprintf(stderr, "no comparison selected\n");
#endif
return 0;
}
示例6: tright
// Tests each blob in the list to see if it is certain non-text using 2
// conditions:
// 1. blob overlaps a cell with high value in noise_density_ (previously set
// by ComputeNoiseDensity).
// OR 2. The blob overlaps more than max_blob_overlaps in *this grid. This
// condition is disabled with max_blob_overlaps == -1.
// If it does, the blob is declared non-text, and is used to mark up the
// nontext_mask. Such blobs are fully deleted, and non-noise blobs have their
// neighbours reset, as they may now point to deleted data.
// WARNING: The blobs list blobs may be in the *this grid, but they are
// not removed. If any deleted blobs might be in *this, then this must be
// Clear()ed immediately after MarkAndDeleteNonTextBlobs is called.
// If the win is not NULL, deleted blobs are drawn on it in red, and kept
// blobs are drawn on it in ok_color.
void CCNonTextDetect::MarkAndDeleteNonTextBlobs(BLOBNBOX_LIST* blobs,
int max_blob_overlaps,
ScrollView* win,
ScrollView::Color ok_color,
Pix* nontext_mask) {
int imageheight = tright().y() - bleft().x();
BLOBNBOX_IT blob_it(blobs);
BLOBNBOX_LIST dead_blobs;
BLOBNBOX_IT dead_it(&dead_blobs);
for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
BLOBNBOX* blob = blob_it.data();
TBOX box = blob->bounding_box();
if (!noise_density_->RectMostlyOverThreshold(box, max_noise_count_) &&
(max_blob_overlaps < 0 ||
!BlobOverlapsTooMuch(blob, max_blob_overlaps))) {
blob->ClearNeighbours();
#ifndef GRAPHICS_DISABLED
if (win != NULL)
blob->plot(win, ok_color, ok_color);
#endif // GRAPHICS_DISABLED
} else {
if (noise_density_->AnyZeroInRect(box)) {
// There is a danger that the bounding box may overlap real text, so
// we need to render the outline.
Pix* blob_pix = blob->cblob()->render_outline();
pixRasterop(nontext_mask, box.left(), imageheight - box.top(),
box.width(), box.height(), PIX_SRC | PIX_DST,
blob_pix, 0, 0);
pixDestroy(&blob_pix);
} else {
if (box.area() < gridsize() * gridsize()) {
// It is a really bad idea to make lots of small components in the
// photo mask, so try to join it to a bigger area by expanding the
// box in a way that does not touch any zero noise density cell.
box = AttemptBoxExpansion(box, *noise_density_, gridsize());
}
// All overlapped cells are non-zero, so just mark the rectangle.
pixRasterop(nontext_mask, box.left(), imageheight - box.top(),
box.width(), box.height(), PIX_SET, NULL, 0, 0);
}
#ifndef GRAPHICS_DISABLED
if (win != NULL)
blob->plot(win, ScrollView::RED, ScrollView::RED);
#endif // GRAPHICS_DISABLED
// It is safe to delete the cblob now, as it isn't used by the grid
// or BlobOverlapsTooMuch, and the BLOBNBOXes will go away with the
// dead_blobs list.
// TODO(rays) delete the delete when the BLOBNBOX destructor deletes
// the cblob.
delete blob->cblob();
dead_it.add_to_end(blob_it.extract());
}
}
}
示例7: pixaDisplay
/*!
* pixaDisplay()
*
* Input: pixa
* w, h (if set to 0, determines the size from the
* b.b. of the components in pixa)
* Return: pix, or null on error
*
* Notes:
* (1) This uses the boxes to place each pix in the rendered composite.
* (2) Set w = h = 0 to use the b.b. of the components to determine
* the size of the returned pix.
* (3) Uses the first pix in pixa to determine the depth.
* (4) The background is written "white". On 1 bpp, each successive
* pix is "painted" (adding foreground), whereas for grayscale
* or color each successive pix is blitted with just the src.
* (5) If the pixa is empty, returns an empty 1 bpp pix.
*/
PIX *
pixaDisplay(PIXA *pixa,
l_int32 w,
l_int32 h)
{
l_int32 i, n, d, xb, yb, wb, hb;
BOXA *boxa;
PIX *pixt, *pixd;
PROCNAME("pixaDisplay");
if (!pixa)
return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
n = pixaGetCount(pixa);
if (n == 0 && w == 0 && h == 0)
return (PIX *)ERROR_PTR("no components; no size", procName, NULL);
if (n == 0) {
L_WARNING("no components; returning empty 1 bpp pix", procName);
return pixCreate(w, h, 1);
}
/* If w and h not input, determine the minimum size required
* to contain the origin and all c.c. */
if (w == 0 || h == 0) {
boxa = pixaGetBoxa(pixa, L_CLONE);
boxaGetExtent(boxa, &w, &h, NULL);
boxaDestroy(&boxa);
}
/* Use the first pix in pixa to determine the depth. */
pixt = pixaGetPix(pixa, 0, L_CLONE);
d = pixGetDepth(pixt);
pixDestroy(&pixt);
if ((pixd = pixCreate(w, h, d)) == NULL)
return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
if (d > 1)
pixSetAll(pixd);
for (i = 0; i < n; i++) {
if (pixaGetBoxGeometry(pixa, i, &xb, &yb, &wb, &hb)) {
L_WARNING("no box found!", procName);
continue;
}
pixt = pixaGetPix(pixa, i, L_CLONE);
if (d == 1)
pixRasterop(pixd, xb, yb, wb, hb, PIX_PAINT, pixt, 0, 0);
else
pixRasterop(pixd, xb, yb, wb, hb, PIX_SRC, pixt, 0, 0);
pixDestroy(&pixt);
}
return pixd;
}
示例8: step
// Renders the outline to the given pix, with left and top being
// the coords of the upper-left corner of the pix.
void C_OUTLINE::render(int left, int top, Pix* pix) const {
ICOORD pos = start;
for (int stepindex = 0; stepindex < stepcount; ++stepindex) {
ICOORD next_step = step(stepindex);
if (next_step.y() < 0) {
pixRasterop(pix, 0, top - pos.y(), pos.x() - left, 1,
PIX_NOT(PIX_DST), NULL, 0, 0);
} else if (next_step.y() > 0) {
pixRasterop(pix, 0, top - pos.y() - 1, pos.x() - left, 1,
PIX_NOT(PIX_DST), NULL, 0, 0);
}
pos += next_step;
}
}
示例9: pixConnCompTransform
/*!
* \brief pixConnCompTransform()
*
* \param[in] pixs 1 bpp
* \param[in] connect connectivity: 4 or 8
* \param[in] depth of pixd: 8 or 16 bpp; use 0 for auto determination
* \return pixd 8, 16 or 32 bpp, or NULL on error
*
* <pre>
* Notes:
* (1) pixd is 8, 16 or 32 bpp, and the pixel values label the
* fg component, starting with 1. Pixels in the bg are labelled 0.
* (2) If %depth = 0, the depth of pixd is 8 if the number of c.c.
* is less than 254, 16 if the number of c.c is less than 0xfffe,
* and 32 otherwise.
* (3) If %depth = 8, the assigned label for the n-th component is
* 1 + n % 254. We use mod 254 because 0 is uniquely assigned
* to black: e.g., see pixcmapCreateRandom(). Likewise,
* if %depth = 16, the assigned label uses mod(2^16 - 2), and
* if %depth = 32, no mod is taken.
* </pre>
*/
PIX *
pixConnCompTransform(PIX *pixs,
l_int32 connect,
l_int32 depth)
{
l_int32 i, n, index, w, h, xb, yb, wb, hb;
BOXA *boxa;
PIX *pix1, *pix2, *pixd;
PIXA *pixa;
PROCNAME("pixConnCompTransform");
if (!pixs || pixGetDepth(pixs) != 1)
return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
if (connect != 4 && connect != 8)
return (PIX *)ERROR_PTR("connectivity must be 4 or 8", procName, NULL);
if (depth != 0 && depth != 8 && depth != 16 && depth != 32)
return (PIX *)ERROR_PTR("depth must be 0, 8, 16 or 32", procName, NULL);
boxa = pixConnComp(pixs, &pixa, connect);
n = pixaGetCount(pixa);
boxaDestroy(&boxa);
pixGetDimensions(pixs, &w, &h, NULL);
if (depth == 0) {
if (n < 254)
depth = 8;
else if (n < 0xfffe)
depth = 16;
else
depth = 32;
}
pixd = pixCreate(w, h, depth);
pixSetSpp(pixd, 1);
if (n == 0) { /* no fg */
pixaDestroy(&pixa);
return pixd;
}
/* Label each component and blit it in */
for (i = 0; i < n; i++) {
pixaGetBoxGeometry(pixa, i, &xb, &yb, &wb, &hb);
pix1 = pixaGetPix(pixa, i, L_CLONE);
if (depth == 8) {
index = 1 + (i % 254);
pix2 = pixConvert1To8(NULL, pix1, 0, index);
} else if (depth == 16) {
index = 1 + (i % 0xfffe);
pix2 = pixConvert1To16(NULL, pix1, 0, index);
} else { /* depth == 32 */
index = 1 + i;
pix2 = pixConvert1To32(NULL, pix1, 0, index);
}
pixRasterop(pixd, xb, yb, wb, hb, PIX_PAINT, pix2, 0, 0);
pixDestroy(&pix1);
pixDestroy(&pix2);
}
pixaDestroy(&pixa);
return pixd;
}
示例10: GetBinaryImage
/**
* Returns an image of the current object at the given level in greyscale
* if available in the input. To guarantee a binary image use BinaryImage.
* NOTE that in order to give the best possible image, the bounds are
* expanded slightly over the binary connected component, by the supplied
* padding, so the top-left position of the returned image is returned
* in (left,top). These will most likely not match the coordinates
* returned by BoundingBox.
* Use pixDestroy to delete the image after use.
*/
Pix* PageIterator::GetImage(PageIteratorLevel level, int padding,
int* left, int* top) const {
int right, bottom;
if (!BoundingBox(level, left, top, &right, &bottom))
return NULL;
Pix* pix = tesseract_->pix_grey();
if (pix == NULL)
return GetBinaryImage(level);
// Expand the box.
*left = MAX(*left - padding, 0);
*top = MAX(*top - padding, 0);
right = MIN(right + padding, rect_width_);
bottom = MIN(bottom + padding, rect_height_);
Box* box = boxCreate(*left, *top, right - *left, bottom - *top);
Pix* grey_pix = pixClipRectangle(pix, box, NULL);
boxDestroy(&box);
if (level == RIL_BLOCK) {
Pix* mask = it_->block()->block->render_mask();
Pix* expanded_mask = pixCreate(right - *left, bottom - *top, 1);
pixRasterop(expanded_mask, padding, padding,
pixGetWidth(mask), pixGetHeight(mask),
PIX_SRC, mask, 0, 0);
pixDestroy(&mask);
pixDilateBrick(expanded_mask, expanded_mask, 2*padding + 1, 2*padding + 1);
pixInvert(expanded_mask, expanded_mask);
pixSetMasked(grey_pix, expanded_mask, 255);
pixDestroy(&expanded_mask);
}
return grey_pix;
}
示例11: pixAddWithIndicator
/*!
* pixAddWithIndicator()
*
* Input: pixs (1 bpp pix from which components are added; in-place)
* pixa (of connected components, some of which will be put
* into pixs)
* na (numa indicator: add components corresponding to 1s)
* Return: 0 if OK, 1 on error
*
* Notes:
* (1) This complements pixRemoveWithIndicator(). Here, the selected
* components are added to pixs.
*/
l_int32
pixAddWithIndicator(PIX *pixs,
PIXA *pixa,
NUMA *na)
{
l_int32 i, n, ival, x, y, w, h;
BOX *box;
PIX *pix;
PROCNAME("pixAddWithIndicator");
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if (!pixa)
return ERROR_INT("pixa not defined", procName, 1);
if (!na)
return ERROR_INT("na not defined", procName, 1);
n = pixaGetCount(pixa);
if (n != numaGetCount(na))
return ERROR_INT("pixa and na sizes not equal", procName, 1);
for (i = 0; i < n; i++) {
numaGetIValue(na, i, &ival);
if (ival == 1) {
pix = pixaGetPix(pixa, i, L_CLONE);
box = pixaGetBox(pixa, i, L_CLONE);
boxGetGeometry(box, &x, &y, &w, &h);
pixRasterop(pixs, x, y, w, h, PIX_SRC | PIX_DST, pix, 0, 0);
boxDestroy(&box);
pixDestroy(&pix);
}
}
return 0;
}
示例12: pixClone
// Compute the connected components in a line
Boxa * CubeLineSegmenter::ComputeLineConComps(Pix *line_mask_pix,
Box *line_box,
Pixa **con_comps_pixa) {
// clone the line mask
Pix *line_pix = pixClone(line_mask_pix);
if (line_pix == NULL) {
return NULL;
}
// AND with the image to get the actual line
pixRasterop(line_pix, 0, 0, line_pix->w, line_pix->h,
PIX_SRC & PIX_DST, img_, line_box->x, line_box->y);
// compute the connected components of the line to be merged
Boxa *line_con_comps = pixConnComp(line_pix, con_comps_pixa, 8);
pixDestroy(&line_pix);
// offset boxes by the bbox of the line
for (int con = 0; con < line_con_comps->n; con++) {
line_con_comps->box[con]->x += line_box->x;
line_con_comps->box[con]->y += line_box->y;
}
return line_con_comps;
}
示例13: main
main(int argc,
char **argv)
{
l_int32 i, j, equal;
PIX *pixs, *pixt, *pixd;
static char mainName[] = "rasteropip_reg";
pixs = pixRead("test8.jpg");
pixt = pixCopy(NULL, pixs);
/* Copy, in-place and one COLUMN at a time, from the right
side to the left side. */
for (j = 0; j < 200; j++)
pixRasterop(pixs, 20 + j, 20, 1, 250, PIX_SRC, pixs, 250 + j, 20);
pixDisplay(pixs, 50, 50);
/* Copy, in-place and one ROW at a time, from the right
side to the left side. */
for (i = 0; i < 250; i++)
pixRasterop(pixt, 20, 20 + i, 200, 1, PIX_SRC, pixt, 250, 20 + i);
pixDisplay(pixt, 620, 50);
/* Test */
pixEqual(pixs, pixt, &equal);
if (equal)
fprintf(stderr, "OK: images are the same\n");
else
fprintf(stderr, "Error: images are different\n");
pixWrite("/tmp/junkpix.png", pixs, IFF_PNG);
pixDestroy(&pixs);
pixDestroy(&pixt);
/* Show the mirrored border, which uses the general
pixRasterop() on an image in-place. */
pixs = pixRead("test8.jpg");
pixt = pixRemoveBorder(pixs, 40);
pixd = pixAddMirroredBorder(pixt, 25, 25, 25, 25);
pixDisplay(pixd, 50, 550);
pixDestroy(&pixs);
pixDestroy(&pixt);
pixDestroy(&pixd);
return 0;
}
示例14: main
main(int argc,
char **argv)
{
l_int32 i, j, w, h, same, width, height, cx, cy;
l_uint32 val;
PIX *pixs, *pixse, *pixd1, *pixd2;
SEL *sel;
static char mainName[] = "rasterop_reg";
if (argc != 1)
return ERROR_INT(" Syntax: rasterop_reg", mainName, 1);
pixs = pixRead("feyn.tif");
for (width = 1; width <= 25; width += 3) {
for (height = 1; height <= 25; height += 4) {
cx = width / 2;
cy = height / 2;
/* Dilate using an actual sel */
sel = selCreateBrick(height, width, cy, cx, SEL_HIT);
pixd1 = pixDilate(NULL, pixs, sel);
/* Dilate using a pix as a sel */
pixse = pixCreate(width, height, 1);
pixSetAll(pixse);
pixd2 = pixCopy(NULL, pixs);
w = pixGetWidth(pixs);
h = pixGetHeight(pixs);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
pixGetPixel(pixs, j, i, &val);
if (val)
pixRasterop(pixd2, j - cx, i - cy, width, height,
PIX_SRC | PIX_DST, pixse, 0, 0);
}
}
pixEqual(pixd1, pixd2, &same);
if (same == 1)
fprintf(stderr, "Correct for (%d,%d)\n", width, height);
else {
fprintf(stderr, "Error: results are different!\n");
fprintf(stderr, "SE: width = %d, height = %d\n", width, height);
pixWrite("/tmp/junkout1", pixd1, IFF_PNG);
pixWrite("/tmp/junkout2", pixd2, IFF_PNG);
return 1;
}
pixDestroy(&pixse);
pixDestroy(&pixd1);
pixDestroy(&pixd2);
selDestroy(&sel);
}
}
pixDestroy(&pixs);
return 0;
}
示例15: pixEmbedForRotation
/*!
* pixEmbedForRotation()
*
* Input: pixs (1, 2, 4, 8, 32 bpp rgb)
* angle (radians; clockwise is positive)
* incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
* width (original width; use 0 to avoid embedding)
* height (original height; use 0 to avoid embedding)
* Return: pixd, or null on error
*
* Notes:
* (1) For very small rotations, just return a clone.
* (2) Generate larger image to embed pixs if necessary, and
* place the center of the input image in the center.
* (3) Rotation brings either white or black pixels in
* from outside the image. For colormapped images where
* there is no white or black, a new color is added if
* possible for these pixels; otherwise, either the
* lightest or darkest color is used. In most cases,
* the colormap will be removed prior to rotation.
* (4) The dest is to be expanded so that no image pixels
* are lost after rotation. Input of the original width
* and height allows the expansion to stop at the maximum
* required size, which is a square with side equal to
* sqrt(w*w + h*h).
* (5) For an arbitrary angle, the expansion can be found by
* considering the UL and UR corners. As the image is
* rotated, these move in an arc centered at the center of
* the image. Normalize to a unit circle by dividing by half
* the image diagonal. After a rotation of T radians, the UL
* and UR corners are at points T radians along the unit
* circle. Compute the x and y coordinates of both these
* points and take the max of absolute values; these represent
* the half width and half height of the containing rectangle.
* The arithmetic is done using formulas for sin(a+b) and cos(a+b),
* where b = T. For the UR corner, sin(a) = h/d and cos(a) = w/d.
* For the UL corner, replace a by (pi - a), and you have
* sin(pi - a) = h/d, cos(pi - a) = -w/d. The equations
* given below follow directly.
*/
PIX *
pixEmbedForRotation(PIX *pixs,
l_float32 angle,
l_int32 incolor,
l_int32 width,
l_int32 height)
{
l_int32 w, h, d, w1, h1, w2, h2, maxside, wnew, hnew, xoff, yoff, setcolor;
l_float64 sina, cosa, fw, fh;
PIX *pixd;
PROCNAME("pixEmbedForRotation");
if (!pixs)
return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
return (PIX *)ERROR_PTR("invalid incolor", procName, NULL);
if (L_ABS(angle) < MIN_ANGLE_TO_ROTATE)
return pixClone(pixs);
/* Test if big enough to hold any rotation of the original image */
pixGetDimensions(pixs, &w, &h, &d);
maxside = (l_int32)(sqrt((l_float64)(width * width) +
(l_float64)(height * height)) + 0.5);
if (w >= maxside && h >= maxside) /* big enough */
return pixClone(pixs);
/* Find the new sizes required to hold the image after rotation.
* Note that the new dimensions must be at least as large as those
* of pixs, because we're rasterop-ing into it before rotation. */
cosa = cos(angle);
sina = sin(angle);
fw = (l_float64)w;
fh = (l_float64)h;
w1 = (l_int32)(L_ABS(fw * cosa - fh * sina) + 0.5);
w2 = (l_int32)(L_ABS(-fw * cosa - fh * sina) + 0.5);
h1 = (l_int32)(L_ABS(fw * sina + fh * cosa) + 0.5);
h2 = (l_int32)(L_ABS(-fw * sina + fh * cosa) + 0.5);
wnew = L_MAX(w, L_MAX(w1, w2));
hnew = L_MAX(h, L_MAX(h1, h2));
if ((pixd = pixCreate(wnew, hnew, d)) == NULL)
return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
pixCopyResolution(pixd, pixs);
pixCopyColormap(pixd, pixs);
pixCopySpp(pixd, pixs);
pixCopyText(pixd, pixs);
xoff = (wnew - w) / 2;
yoff = (hnew - h) / 2;
/* Set background to color to be rotated in */
setcolor = (incolor == L_BRING_IN_BLACK) ? L_SET_BLACK : L_SET_WHITE;
pixSetBlackOrWhite(pixd, setcolor);
/* Rasterop automatically handles all 4 channels for rgba */
pixRasterop(pixd, xoff, yoff, w, h, PIX_SRC, pixs, 0, 0);
return pixd;
}