2014年8月11日 星期一

Photoshop 影像處理小記

since: 2014/08/08
update: 2014/08/11

A. 說明:

    1. 利用 Photoshop 來對照片作適當的後製編修.   

    2. 檢查版本更新: Help > Updates...


    3. 檢查支援
Camera Raw 的版本:
        Photoshop > About Plug-In > Camera Raw...



    4. 設定用滑鼠滾輪來放大縮小圖片:
        Photoshop > Preferences > General...


       勾選: Zoom with Scroll Wheel > OK            


                                 
---------------------------------------------------------------------------------------------

B. 查看相片相關資訊:
    (先開啟相片)
    File
> File Info...


    Camera Data > OK(關閉)

---------------------------------------------------------------------------------------------

C. 顯示照片色階圖/ 直方圖(Histogram):
    (先開啟相片)
     右上方 >> (更多選項) > Photography(照片)


    > Expanded View

   > Channel: Luminosity(亮度)

---------------------------------------------------------------------------------------------

D.
調整高光位(Hi Light) 與陰影(Shadow) 的曲線(Curve):
    (先開啟相片)
    Image > Adjustments(調整) > Curves...(曲線)


    操作說明:
     1. 增強對比度: (形成 S 型曲線)
         將紅圈左上方拖曳, 可使亮處更亮
         將藍圈右下方拖曳, 可將暗處更暗

     2. 調整後, 按下 Alt 鍵不放, 可使 Cancel 鍵變成 Reset 鍵.

     3. 按下 "Auto" 可由程式自動調整.

     4. 藉由: 勾選 / 取消勾選 Preview, 可觀看修改前後的差異


    5. 結果比較:
        原始檔:

     調整後: (增強對比)

---------------------------------------------------------------------------------------------
E.
調整色相(Hue) 飽和度(Saturation) 與明度(Lightness):
    (以飽和度為例, 先開啟相片)
    Image > Adjustments(調整) > Hue/Saturation...


   操作說明:
    1. 將顏色選取藍色, 提高飽和度 > OK

    2. 將顏色選取綠色, 降低飽和度 > OK

   3. 結果比較:
       原始檔:


    調整後:(提升藍色飽和度, 降低綠色飽和度)

---------------------------------------------------------------------------------------------

F. 調整色階分佈圖(Levels):

    (先開啟相片)
     Image > Adjustments > Levels...(色階)


     操作說明:
     將中間色調三角標示往左拖曳以提高整體亮度


    結果:
    原始檔:

    調整後:(較亮)

---------------------------------------------------------------------------------------------
G. 調整水平:

    (先開啟相片)
    點選 "Crop Tool" (裁切工具)


    > 滑鼠移至右下方角落, 出現半圓弧雙箭頭符號時, 旋轉角度, 按下 Enter.

    結果:
    原始檔:

    調整後:(正常水平)

---------------------------------------------------------------------------------------------

H.
調整亮度(Brightness)與對比(Contrast):
     Image > Adjustments > Brightness/Contrast...


   > 適當的調整亮度對比, 並注意色階分布圖.

    結果:
    原始檔:

    調整後:

---------------------------------------------------------------------------------------------
I. 進塵處理:

    (先開啟相片)
    點選 "Spot Healing Brush Tool" (汙點修復筆刷工具)


    > 調整筆刷大小, 並在照片上汙點處做處理.

    結果:
    原始檔:

    處理後:

---------------------------------------------------------------------------------------------
J. 移除小點景:

    (先開啟相片)
   
點選 "Clone Stamp Tool" (圖章複製工具), 並先在要移除的點景旁,
    按 ALT 點一下(複製圖樣), 接著在
點景進行貼上(覆蓋)的處理.

    結果:
    原始檔:

    處理後: (移除綠色植物)

---------------------------------------------------------------------------------------------
K.
移除大點景:
    (先開啟相片)
   
點選 "Rectangular Marquee Tool" (矩形選框工具)

    > 框選要移除的景點

    > Edit > Fill...(填滿)

    > 使用: Content-Aware(內容感知)
       透明度: 100 %
    > OK


    結果:    
    原始檔:

    處理後: (貓咪不見了)

2014年5月8日 星期四

OpenCL: Query Device Info

since: 2014/05/08
update: 2014/05/08

reference:
1. Amazon.com: OpenCL Programming by Example
2. I touchs: OpenCL: Query Platforms Info

A. 說明
     本篇文章以 OpenCL: Query Platforms Info 所建的專案為主, 來進行功能的修改.

---------------------------------------------------------------------------------------------

B. 幫專案新增檔案
     1. 在專案的 Utility 群組裡, 新增檔案:
          QueryDeviceInfo.h
QueryDeviceInfo.cpph

     2. 專案結構如下:


---------------------------------------------------------------------------------------------

C. 撰寫程式碼
     1. 開啓 QueryDeviceInfo.h 檔案, 修改如下
/*
#ifndef __HelloOpenCL__QueryDeviceInfo__
#define __HelloOpenCL__QueryDeviceInfo__

#include <iostream>

#endif

*/

//@add
#include "OpenCLHeader.h"

void PrintDeviceInfo(cl_device_id device);


**********************************************************************

     2. 開啓 QueryDeviceInfo.cpp 檔案, 修改如下
#include "QueryDeviceInfo.h"

void PrintDeviceInfo(cl_device_id device)
{
    char queryBuffer[1024];
    int queryInt;
    cl_int clError;
    cl_device_type dev_type;
    size_t ret_size;
    cl_uint entries;
    cl_bool bool_entries;
   
    // Get DEVICE_TYPE
    clError = clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(dev_type), &dev_type, &ret_size);
    printf("Device Type: ");
    if(dev_type & CL_DEVICE_TYPE_GPU) printf("CL_DEVICE_TYPE_GPU ");
    if(dev_type & CL_DEVICE_TYPE_CPU) printf("CL_DEVICE_TYPE_CPU ");
    if(dev_type & CL_DEVICE_TYPE_ACCELERATOR) printf("CL_DEVICE_TYPE_ACCELERATOR ");
    if(dev_type & CL_DEVICE_TYPE_DEFAULT) printf("CL_DEVICE_TYPE_DEFAULT ");
    printf("\n");
   
    // Get DEVICE_NAME
    clError = clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(queryBuffer), &queryBuffer, NULL);
    printf("CL_DEVICE_NAME: %s\n", queryBuffer);
    queryBuffer[0] = '\0';
   
    // Get DEVICE_VENDOR
    clError = clGetDeviceInfo(device, CL_DEVICE_VENDOR, sizeof(queryBuffer), &queryBuffer, NULL);
    printf("CL_DEVICE_VENDOR: %s\n", queryBuffer);
    queryBuffer[0] = '\0';
   
    // Get DRIVER_VERSION
    clError = clGetDeviceInfo(device, CL_DRIVER_VERSION, sizeof(queryBuffer), &queryBuffer, NULL);
    printf("CL_DRIVER_VERSION: %s\n", queryBuffer);
    queryBuffer[0] = '\0';
   
    // Get DEVICE_VERSION
    clError = clGetDeviceInfo(device, CL_DEVICE_VERSION, sizeof(queryBuffer), &queryBuffer, NULL);
    printf("CL_DEVICE_VERSION: %s\n", queryBuffer);
    queryBuffer[0] = '\0';
   
    // Get DEVICE_MAX_COMPUTE_UNITS
    clError = clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(int), &queryInt, NULL);
    printf("CL_DEVICE_MAX_COMPUTE_UNITS: %d\n", queryInt);
   
    // Get DEVICE_MAX_CLOCK_FREQUENCY
    clError = clGetDeviceInfo(device, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(cl_uint), &entries, &ret_size);
    printf("CL_DEVICE_MAX_CLOCK_FREQUENCY(Mhz): %d\n", entries);
   
    // Get DEVICE_IMAGE_SUPPORT
    clError = clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &bool_entries, &ret_size);
    printf("Image Support: ");
    if(bool_entries == true) printf("True");
    if(bool_entries == false) printf("False");
    printf("\n");
}


**********************************************************************

     3. 開啓 main.cpp 檔案, 修改如下
#include "QueryDeviceInfo.h"

int main(int argc, const char * argv[])
{
    cl_int           clError;
    cl_platform_id *platforms = NULL;
    cl_uint          num_platforms = 0;
   
    // 第一次呼叫 clGetPlatformIDs, 得到 num_platforms 的值
    clError = clGetPlatformIDs(0, NULL, &num_platforms);
    if(clError != CL_SUCCESS)
    {
        printf("Error in call to clGetPlatformIDs (first) ....\n Exiting");
        exit(0);
    }
   
    printf("Number of OpenCL platforms available in the system: %d\n", num_platforms);
   
    // 再次呼叫 clGetPlatformIDs, 得到 platforms 的值
    platforms = (cl_platform_id *)malloc(sizeof(cl_platform_id)*num_platforms);
    clError = clGetPlatformIDs(num_platforms, platforms, NULL);
    if(clError != CL_SUCCESS)
    {
        free(platforms);
        printf("Error in call to clGetPlatformIDs (second) ....\n Exiting");
        exit(0);
    }

    if (num_platforms == 0)
    {
        free(platforms);
        printf("No OpenCL Platforms Found ....\n Exiting");
        exit(0);
    }
   
    // We have obtained platforms here.
    // Lets enumerate the devices available in this Platform.

    for (cl_uint idx = 0; idx < num_platforms; idx++)
    {
        cl_device_id    *devices;
        cl_uint          num_devices;
        printf("\nPrinting OpenCL Device Info For Platform ID : %d\n\n", idx);
       
        // 第一次呼叫 clGetDeviceIDs, 得到 num_devices 的值
        clError = clGetDeviceIDs (platforms[idx], CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
        if (clError != CL_SUCCESS)
        {
            printf("Error Getting number of devices (first) ... Exiting\n ");
            exit(0);
        }

        // If successfull the num_devices contains the number of devices available in the platform
        // Now lets get all the device list. Before that we need to malloc devices
        // 再次呼叫 clGetPlatformIDs, 得到 devices 的值

        devices = (cl_device_id *)malloc(sizeof(cl_device_id) * num_devices);
        clError = clGetDeviceIDs (platforms[idx], CL_DEVICE_TYPE_ALL, num_devices, devices, &num_devices);
        if (clError != CL_SUCCESS)
        {
            free(devices);
            printf("Error Getting number of devices (second) ... Exiting\n ");
            exit(0);
        }
       
        for (cl_uint dIndex = 0; dIndex < num_devices; dIndex++)
        {
            printf("==================Device No %d======================\n",dIndex);
            PrintDeviceInfo(devices[dIndex]);
            printf("====================================================\n\n");
        }
       
        free(devices);
    }
   
    return 0;
}


---------------------------------------------------------------------------------------------

D. 執行結果

2014年4月25日 星期五

OpenCL: Query Platforms Info


since: 2014/04/25
update: 2014/04/25

reference:
1. Amazon.com: OpenCL Programming by Example
2. VIML-OpenCL 簡介
3. OpenCL 教學(一) - Hotball's Hive
4. Richard's blog: OpenCL 介紹
5. OpenCL - leon的专栏
6. Khronos 2013 - opencl_overview.pdf
7. OpenCL Programming Guide for Mac: About OpenCL for OS X
8. OpenCL 1.2 Reference Pages

A. 前言
     1. 本系列學習 OpenCL 的文章主要的參考來源是:
         a. 電子書: Amazon.com: OpenCL Programming by Example
         b. 網路文章

     2. 詳細的基本觀念說明, 請參考上方 reference 裡的文章.

     3. 以 OpenCL 1.2 為主要的版本.

---------------------------------------------------------------------------------------------

B. 測試環境 (只用貼圖, 越來越懶了我...)


---------------------------------------------------------------------------------------------

C. 相關觀念說明
     1. OpenCL Platform(平台)
         何謂 OpenCL Platform? 簡單來說, 就是不同的硬體廠商(ex: AMD, Intel,
         NVIDIA...)依照硬體架構所提供 OpenCL 實作framework / SDK,
         在 PC 上, 可以存在多個 OpenCL Platform, 而在 Mac 上只有一個.

     2. OpenCL Platform Model


         a. 主機上的 CPU 會與一個或多個 OpenCL devices(CPU, GPU, DSP...) 作連結.
             (A host is connected to one or more OpenCL devices)

         b. OpenCL device 聚集了一組或多組的計算單位.
             (OpenCL device is collection of one or more compute units)

         c. 一組計算單位是由一個或多個處理元素所組成
             (A compute unit is composed of one or more processing elements)

         d. 處理元素是以 "單一指令多筆資料" 或 "單一程序多筆資料" 的方式來執行程式碼.
             (Processing elements execute code as SIMD or SPMD)
             備註: SIMD: single Instruction, Multiple Data
                     SPMD: single program, multiple data


---------------------------------------------------------------------------------------------

D. 新增專案
     1. Xcode > File > New > Project...
         OS X > Application > Command Line Tool


     2. Choose options for your project:
         Product Name: HelloOpenCL
         Type: C++
          > Next

         備註: Type 可以選擇 C, 在這邊是預留以後可以加入 C++ 的程式

     3. 加入 OpenCL framework: OpenCL.framework


     4. 幫專案新增一個叫作 Utility 的群組: 
         > 在此群組內, 新增檔案: OpenCLHeader.h, QueryPlatformInfo.h
            與 QueryPlatformInfo.cpp

     5. 專案結構如下:


---------------------------------------------------------------------------------------------

E. 撰寫程式碼
     1. 標頭檔: 開啓 OpenCLHeader.h 檔案, 修改如下
/*
#ifndef HelloOpenCL_OpenCLHeader_h
#define HelloOpenCL_OpenCLHeader_h

#endif

*/

//@add
#include <stdio.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif


*************************************************************


     2. 開啓 QueryPlatformInfo.h 檔案, 修改如下
/*
#ifndef HelloOpenCL_QueryPlatformInfo_h
#define HelloOpenCL_QueryPlatformInfo_h

#endif

*/

//@add
#include "OpenCLHeader.h"

void PrintPlatformInfo(cl_platform_id platform);


*************************************************************

     3. 開啓 QueryPlatformInfo.cpp 檔案, 修改如下
#include "QueryPlatformInfo.h"

//@add
void PrintPlatformInfo(cl_platform_id platform)
{
    char queryBuffer[1024];
    cl_int clError;
   
    clError = clGetPlatformInfo (platform, CL_PLATFORM_NAME, 1024, &queryBuffer, NULL);
    if(clError == CL_SUCCESS)
    {
        printf("CL_PLATFORM_NAME   : %s\n", queryBuffer);
    }

    clError = clGetPlatformInfo (platform, CL_PLATFORM_VENDOR, 1024, &queryBuffer, NULL);
    if(clError == CL_SUCCESS)
    {
        printf("CL_PLATFORM_VENDOR : %s\n", queryBuffer);
    }

    clError = clGetPlatformInfo (platform, CL_PLATFORM_VERSION, 1024, &queryBuffer, NULL);
    if (clError == CL_SUCCESS)
    {
        printf("CL_PLATFORM_VERSION: %s\n", queryBuffer);
    }

    clError = clGetPlatformInfo (platform, CL_PLATFORM_PROFILE, 1024, &queryBuffer, NULL);
    if (clError == CL_SUCCESS)
    {
        printf("CL_PLATFORM_PROFILE: %s\n", queryBuffer);
    }

    clError = clGetPlatformInfo (platform, CL_PLATFORM_EXTENSIONS, 1024, &queryBuffer, NULL);
    if (clError == CL_SUCCESS)
    {
        printf("CL_PLATFORM_EXTENSIONS: %s\n", queryBuffer);
    }

    return;
}


*************************************************************


     4. 開啓 main.cpp 檔案, 修改如下
//#include <iostream>
//@add
#include "QueryPlatformInfo.h"


int main(int argc, const char * argv[])
{
    // insert code here...
    //std::cout << "Hello, World!\n";

   
    //@add
    cl_int           clError;
    cl_platform_id *platforms = NULL;
    cl_uint          num_platforms;

    // Get the number of Platforms available
    // Note that the second parameter "platforms" is set to NULL.
    // If this is NULL then this argument is ignored
    // and the API returns the total number of OpenCL platforms available. 

    // 先呼叫 clGetPlatformIDs, 以得到 num_platforms 的值
    clError = clGetPlatformIDs(0, NULL, &num_platforms);
    if(clError != CL_SUCCESS)
    {
        printf("Error in call to clGetPlatformIDs....\n Exiting");
        exit(0);
    }
    else
    {
        if (num_platforms == 0)
        {
            printf("No OpenCL Platforms Found ....\n Exiting");
        }
        else
        {
            //Allocate memory for OpenCL platforms.
            printf ("Found %d Platforms\n", num_platforms);
            platforms = (cl_platform_id *)malloc(num_platforms * sizeof(cl_platform_id));

            // Get the platform id's
            // In contrast to the above call with "platforms" as NULL. The below call actually fills the buffer with
            // the platform IDs. It will list the platforms upto the value specified by num_platforms. One should make
            // sure that the appropriate buffer size is allocated.
           
            // 
再次呼叫 clGetPlatformIDs, 得到 platforms 的值           
            clError = clGetPlatformIDs (num_platforms, platforms, NULL);


            // for each platform now start printing the information

            for(cl_uint index = 0; index < num_platforms; index++)
            {
                printf("==================Platform No %d======================\n",index);
                PrintPlatformInfo(platforms[index]);
                printf("======================================================\n\n");
            }
        }
    }
   
    return 0;
}

---------------------------------------------------------------------------------------------

F. 執行結果: