Implementation of seamless splicing of fragmented images using VC ++

Source: Internet
Author: User

[Article Information]
 
Author: Lang Rui, Qingdao branch, 22nd Research Institute, China Electronics Technology Group Corporation
Time: Source: Skynet responsibility Editor: Ark
 
[Document Introduction]
 
This article describes the implementation principle and process of the seamless splicing technology for multiple fragment images under VC ++ 6.0.
 

Summary: This article describes the implementation principle and process of seamless splicing of multiple fragment images under Microsoft Visual C ++ 6.0, and provides some key code for reference.

  Keywords: Microsoft Visual C ++ 6.0, images, seamless splicing, bitmap files

  I. Introduction

In surveying and mapping, Wenbo, and other industries, we often encounter the following situation: the object to be observed is relatively large. To ensure resolution and not to take all of the images, we can only take partial photos, remove the overlapping parts of these local photos and combine them into a complete image. In the past, we often used manual splicing, which has a large error and often cannot achieve seamless splicing. Even with a small number of professional equipment, the cost is generally high. In fact, you only need to input a photo into the computer through a scanner, and process it through a program. This allows you to seamlessly combine multiple images to meet your actual needs, moreover, the broken and irregular objects, such as fragments of old words and paintings, that are often encountered in the Wenbo industry can also be seamlessly combined. This article briefly introduces the implementation principle and process of the program.

  Ii. Program Design Principles

First, we start from the reality. We store all the information as a whole through local photography, however, it is necessary to ensure that the information contained in these local photos and all the information included in the whole will inevitably overlap each of the two adjacent images, in this way, we can ensure that no information is missed during the process of dividing the entire object into several partial photos and then merging the entire image. That is, the entire process of division and splicing is lossless. In this case, we only need to ensure that the overlapping parts of the adjacent images can overlap completely, so we can be sure that the two images in this state have achieved seamless splicing. Therefore, the problem is to make the overlapping parts of adjacent images completely overlap, and to determine whether the two identical image fragments completely overlap, the grating mask can be used for intuitive judgment, for example, we can use an "exclusive or" Mask. When the pixels of two images at the same position are 0 or black at the same time, we can move the two images, as long as the overlapping part is completely black, it indicates that the overlapping part of the two images has been accurately overlapped, and at this time the image is seamlessly combined. After that, you only need to use the "or" grating mask to display the merged image, and then store it on the disk through Screen Copy. In the whole process of splicing, it mainly involves image drag-and-drop, Image File Reading and display, grating mask, domestic screen, memory bitmap storage, and other technologies. Next, we will introduce the specific applications of these technologies.

  Iii. Specific implementation of the program

Before splicing, read the image input from the scanner to the memory and display it. Because the grating operation mask adopted in combination is "different or", in order to keep the original appearance of the image, you can use the patblt function in the response function of the message wm_erasebkgnd to set the initial background of the entire customer zone to Black:

......
PDC-> patblt (0, 0, rect. Width (), rect. Height (), blackness );
Return true;

You can use the LoadImage function to read bitmap files. m_spath1 specifies the file path, and the lr_loadfromfile attribute specifies to read bitmap from the file. The returned value is the handle of the bitmap:

......
Hbitmap;
Hbitmap = (hbitmap) LoadImage (AfxGetInstanceHandle (),
M_spath1,
Image_bitmap, 0, 0,
Lr_loadfromfile | lr_createdibsection );

Then we can create a memory device environment hmemdc1 that is compatible with the current device environment, and place the bitmap read to the memory to the device environment:

Hmemdc1 =: createcompatibledc (null );
SelectObject (hmemdc1, hbitmap );
: Deleteobject (hbitmap); // release the used bitmap handle.
Invalidate ();

As for bitmap display, it is more reasonable to place it in the ondraw function due to frequent drag and other processing. to update the display, you only need to explicitly use the invalidate () function to refresh it. Bitblt is recommended for bitblt in the display bitmap part of ondraw (). This function places bitmaps in hmemdc1 on the PDC page to replace the Memory Page. The processing speed is relatively fast:

......
: Bitblt (PDC-> m_hdc, m_nx1, m_ny1, m_nwidth1, m_nheight1,
Hmemdc1, 0, 0, m_dwdrop );
......

The m_dwdrop variable in the function is used to set the grating operation code. The initial value is SRCINVERT, that is, the grating exclusive or operation. When the combination is successful, the result must be displayed as a srcpaint grating or operation.

We can program the mouse message response function to implement bitmap drag and drop in the customer's zone. According to the habits of the Windows system, we first use the ptinrect () the function determines whether the mouse is on the bitmap when it is pressed with the left mouse button. If so, you can drag the image with the mouse before the left mouse button pops up, obviously, this part should be written in the response function of the wm_mousemove message:

......
If (m_bcanmove1 = true) // before moving, the left mouse button is clicked on the image.
{
Int dx = m_nOldX1-m_nX1; // calculates the distance from the mouse to the image Origin
Int DY = m_nOldY1-m_nY1;
M_nx1 = point. X-DX; // calculate the coordinates of the new image origin (client Region coordinates)
M_ny1 = point. Y-dy;
Invalidate (); // update the view
}
M_noldx1 = point. X; // save the last mouse position
M_noldy1 = point. Y;
......

So far, you can run a program to splice multiple fragment images and move an image on the edge of the other image by dragging the mouse. Because of the "exclusive or" grating mask, the color of the overlapping parts of the two images will change, but it will only be black when it is completely re-matched, indicating that the combination is seamless, replace the mask with "or" to display the assembled image. At this time, the merged image storage disk can be retained only when it is stored in the memory and further processed.

First, you need to determine the position and size of the rectangular frame where the merged image is located. You can use the following code to complete this process (in this example, you can splice up to four images at the same time ):

......
Int temp1, temp2, x0, y0, X1, Y1;
Temp1 = m_nx1 <m_nx2? M_nx1: m_nx2;
If (m_spath3! = "") // If three images are involved in Splicing
{
If (m_spath4! = "") // If four images are involved in Splicing
Temp2 = m_nx3 <m_nx4? M_nx3: m_nx4;
Else
Temp2 = m_nx3;
X0 = temp1 <temp2? Temp1: temp2;
}
Else
X0 = temp1;
......
Temp1 = m_nx1 + m_nwidth1> m_nx2 + m_nwid2? M_nx1 + m_nwidth1: m_nx2 + m_nwid2;
If (m_spath3! = "")
{
If (m_spath4! = "")
Temp2 = m_nx3 + m_nwidth3> m_nx4 + m_nwidth4? M_nx3 + m_nwidth3: m_nx4 + m_nwidth4;
Else
Temp2 = m_nx3 + m_nwidth3;
X1 = temp1> temp2? Temp1: temp2;
}
Else
X1 = temp1;

You can use similar code to calculate y0 and Y1. Before the screen is executed, the rectangle composed of x0, y0, X1, and Y1 must be converted into screen coordinates by the customer, which can be implemented using the clienttoscreen () function. The following is the main implementation code of the function that copies the specified area of the screen to the memory as a bitmap:

Hbitmap cimageview: copyscreentobitmap (lprect)
{
......
// Make sure that the selected area is not empty.
If (isrectempty (lprect ))
Return NULL;
// Create a device description table for the screen
Hscrdc = createdc ("display", null );
// Create a compatible memory device description table for the screen device description table
Hmemdc = createcompatibledc (hscrdc );
......
// Create a bitmap compatible with the on-screen device description table
Hbitmap = createcompatiblebitmap (hscrdc, lprect-> width (), lprect-> height ());
// Select the new bitmap to the memory device description table.
Holdbitmap = (hbitmap) SelectObject (hmemdc, hbitmap );
// Copy the screen device description table to the memory device description table.
Bitblt (hmemdc, 0, 0, lprect-> width (), lprect-> height, hscrdc, lprect-> left lprect-> top, srccopy );
// Obtain the handle of the screen bitmap.
Hbitmap = (hbitmap) SelectObject (hmemdc, holdbitmap );
// Clear
Deletedc (hscrdc );
Deletedc (hmemdc );
......
// Returns the bitmap handle.
Return hbitmap;
}

After the spliced area is copied to the memory and the handle of the memory bitmap is obtained, it can be sent to other graphics processing software through the clipboard for further processing, you can also save it as a file in the bitmap format. For convenience, the latter is used in this example. The implementation process is to fill in the information header and pixel array of the BMP file in the format based on the obtained memory bitmap handle. The following describes the implementation of the key code:

First, obtain the device description table handle and use the getdevicecaps () function to obtain the number of bytes occupied by each pixel in the current display resolution. Then, the size of the color palette is calculated:

......
HDC = createdc ("display", null );
Ibits = getdevicecaps (HDC, bitspixel) * getdevicecaps (HDC, PLANeS );
Deletedc (HDC );
If (ibits <= 1)
Wbitcount = 1;
Else if (ibits <= 4)
Wbitcount = 4;
Else if (ibits <= 8)
Wbitcount = 8;
Else if (ibits <= 24)
Wbitcount = 24; // calculate the color palette size
......

Then you can set the bitmap information header structure. Bi is an instance object of the bitmapinfoheader structure:

......
If (wbitcount <= 8)
Dwpalettesize = (1 <wbitcount) * sizeof (rgbquad); // you can specify the Bitmap header structure.
GetObject (hbitmap, sizeof (Bitmap), (lpstr) & Bitmap );
Bi. bisize = sizeof (bitmapinfoheader );
Bi. biwidth = bitmap. bmwidth;
Bi. biheight = bitmap. bmheight;
Bi. biplanes = 1;
Bi. bibitcount = wbitcount;
Bi. bicompression = bi_rgb;
Bi. bisizeimage = 0;
Bi. bixpelspermeter = 0;
Bi. biypelspermeter = 0;
Bi. biclrused = 0;
Bi. biclrimportant = 0;

Use the globalalloc () function to allocate memory for the bitmap content based on the calculation results, return the allocated memory handle hdib, and use getstockobject () to set the default color palette:

......
Dwbmbitssize = (bitmap. bmwidth * wbitcount + 31)/32) * 4 * bitmap. bmheight;
Hdib = globalalloc (ghnd, dwbmbitssize + dwpalettesize + sizeof (bitmapinfoheader ));
Lpbi = (lpbitmapinfoheader) globallock (hdib );
* Lpbi = Bi; // process the color palette
Hpal = getstockobject (default_palette );
If (hpal)
{
HDC =: getdc (null );
Holdpal = selectpalette (HDC, (hpalette) hpal, false );
Realizepalette (HDC );
}
// Obtain the new pixel value under the color palette
Getdibits (HDC, hbitmap, 0, (uint) bitmap. bmheight,
(Lpstr) lpbi + sizeof (bitmapinfoheader) + dwpalettesize,
(Bitmapinfo *) lpbi, dib_rgb_colors );
// Restore the palette
If (holdpal)
{
Selectpalette (HDC, (hpalette) holdpal, true );
Realizepalette (HDC );
: Releasedc (null, HDC );
}
......

The final task is to create a bitmap file. You need to save the configured bitmap file header and pixel lattice information to the file in sequence. bmfhdr is an instance object of the bitmapfileheader bitmap file header structure, you need to set it according to the disk storage format of the BMP bitmap:

......
FH = createfile (lpfilename,
Generic_write, 0, null,
Create_always,
File_attribute_normal | file_flag_sequential_scan, null );
// Set the bitmap file header
Bmfhdr. bftype = 0x4d42; // "BM"
Dwdibsize = sizeof (bitmapfileheader) + sizeof (bitmapinfoheader) + dwpalettesize + dwbmbitssize;
Bmfhdr. bfsize = dwdibsize;
Bmfhdr. bfreserved1 = 0;
Bmfhdr. bfreserved2 = 0;
Bmfhdr. bfoffbits = (DWORD) sizeof (bitmapfileheader) + (DWORD) sizeof (bitmapinfoheader) + dwpalettesize;
// Write the bitmap file header
Writefile (FH, (lpstr) & bmfhdr, sizeof (bitmapfileheader), & dwwritten, null );
// Write the remaining contents of the bitmap file
Writefile (FH, (lpstr) lpbi, dwdibsize, & dwwritten, null );
......

  Iv. program instance detection

The following uses an example to combine the fragments of Ancient Chinese painting to detect the matching effect of the program. Figure 1 to Figure 3 are the three fragments of Ancient Chinese painting before splicing, and figure 4 is the seamless synthesis of images after processing in this program. After detection, the splicing effect is quite good, and there is no joint at the link of the fragment image:


Figure 1


Figure 2

 

Figure 3


Figure 4

 

  Summary:

This program uses an example to describe a practical method for processing images seamlessly, which has great application potential in the surveying, surveying, Wenbo and other industries. On the premise of understanding the program design ideas and programming ideas, combined with the actual needs, through the specific code changes in this article, we can design a similar software that is more suitable for the actual situation of the unit. In addition, the capture and save screen technology described in this article can also provide some reference for the compilation of similar programs. This program is compiled by Microsoft Visual C ++ 2000 under Windows 6.0 professional.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.